ZParam: Set value without changing datatype.

The offical for ZeosLib 7.3 Report problems, ask for help, post proposals for the new version of Zeoslib 7.3/v8
Quick Info:
-We made two new drivers: odbc(raw and unicode version) and oledb
-GUID domain/field-defined support for FB
-extended error infos of Firebird
-performance ups are still in queue
In future some more feature will arrive, so stay tuned and don't hassitate to help
Post Reply
MJFShark
Expert Boarder
Expert Boarder
Posts: 218
Joined: 04.06.2020, 13:59

ZParam: Set value without changing datatype.

Post by MJFShark »

Hey all!

How do you set the value of a ZParam without changing its datatype? Basically I'm wondering if I set the datatype of a ZParam to a date, then how can I set its value using a string while keeping it a datetype? I thought that I could do something like:

MyParam.SQLType := stDate;
MyParam.Value := '2021-04-29'; // Seems to change the datatype to string.

The source documentation talks about "locked" parameter types, so my question may be "How to lock a parameter's datatype" OR am I thinking about this incorrectly and I shouldn't be trying to force a particular datatype in this way? Thanks for any insights!

-Mark
User avatar
aehimself
Zeos Dev Team
Zeos Dev Team
Posts: 797
Joined: 18.11.2018, 17:37
Location: Hungary

Re: ZParam: Set value without changing datatype.

Post by aehimself »

See r7507, this was changed just recently. I *think* it's supposed to work this way but I got no confirmation so this commit can be wrong.
What you want can be achieved by setting the Value first and the type next.
Delphi 12.2, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
MJFShark
Expert Boarder
Expert Boarder
Posts: 218
Joined: 04.06.2020, 13:59

Re: ZParam: Set value without changing datatype.

Post by MJFShark »

I did see that one and changed it (yesterday I think.)

Does setting the value and then the datatype actually do a conversion? I don't see that in my tests.

I see that InternalSetAsXXXX looks like it's capable of doing conversions, but CheckDataIndex sets FSQLDataType to the variant type and then no conversion occurs. I *think* there's something wrong somewhere in there. It's a bit hard to follow as I'm not sure how FSQLType and FSQLDataType relate, and the SQLType property is often masked by local vars and arguments of the same name (which I always worry about.)

I'll do more research and see what I can find.

-Mark
User avatar
EgonHugeist
Zeos Project Manager
Zeos Project Manager
Posts: 1936
Joined: 31.03.2011, 22:38

Re: ZParam: Set value without changing datatype.

Post by EgonHugeist »

Hi,

@aehimself

what was the reason for your pull request? I don't get it. Usually users are setting the param-Type to lock this type. Your patch did change the log vice versa. Can you explain it?

@Mark

i did change that again: https://sourceforge.net/p/zeoslib/code-0/7518/. It should also handle https://sourceforge.net/p/zeoslib/tickets/480/ i bit better. Mark iiuyc then do you expect an implizit converstion from String to TDate, is that correct?
Best regards, Michael

You want to help? http://zeoslib.sourceforge.net/viewtopic.php?f=4&t=3671
You found a (possible) bug? Use the new bugtracker dude! http://sourceforge.net/p/zeoslib/tickets/

Image
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: ZParam: Set value without changing datatype.

Post by marsupilami »

I didn't mention it in the commit but aehimselfs pull request is related to thi: viewtopic.php?p=170902#p170902

Honestly, I think that setting a parameter by using .Value should change the paramtype to whatever data type is in the Variant? Why would we not do it like that?
User avatar
aehimself
Zeos Dev Team
Zeos Dev Team
Posts: 797
Joined: 18.11.2018, 17:37
Location: Hungary

Re: ZParam: Set value without changing datatype.

Post by aehimself »

EgonHugeist wrote: 30.04.2021, 05:44what was the reason for your pull request? I don't get it. Usually users are setting the param-Type to lock this type. Your patch did change the log vice versa. Can you explain it?
As Jan mentioned, an other topic brought the "unknown" type to light. I was unsure about the correct behavior, but typically it's faster to issue a pull request and in case it causes havoc to roll it back than to have an open discussion.

I saw your change this morning, this was the other way it could have been solved. Shame I didn't choose this path :(
Delphi 12.2, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
eversun
Fresh Boarder
Fresh Boarder
Posts: 20
Joined: 28.01.2020, 09:31

Re: ZParam: Set value without changing datatype.

Post by eversun »

Quite possible I have a near problem. I have stored procedure with input parameter of type STRING, but it's internally handled for passing different types (i.e. bigint, float, etc). If I make a call

select * from MYPROC(:VAL)

with Query.ParamByName('VAL').AsLargeInt := 999;

then on Query.Open I got error 'Invalid token'
MJFShark
Expert Boarder
Expert Boarder
Posts: 218
Joined: 04.06.2020, 13:59

Re: ZParam: Set value without changing datatype.

Post by MJFShark »

[update - moved the ReadFormatSettings stuff to a new post]

The new change is good! I just modified the date/time/timestamp conversions to use the nice new ReadFormatSettings. I'm using FConnSettings, but I'm not sure if it should be using a different level. This code was copied from ZDbcCache.pas and while doing this I found a number of cases where ReadFormatSettings.DateFormat is used instead of either TimeFormat or DateTime format. I can do a pull request with the fix, but I'm not around today.

Code: Select all

   // Add     TS: TZTimeStamp; to vars btw
    stDate: if not ZSysUtils.TryUniToDate(P, L, FConSettings^.ReadFormatSettings.DateFormat, PZDate(DataAddr)^) then
              if ZSysUtils.TryUniToTimeStamp(P, L, FConSettings^.ReadFormatSettings.DateTimeFormat, TS{%H-}) then begin
                PZDate(DataAddr)^.Year := TS.Year;
                PZDate(DataAddr)^.Month := TS.Month;
                PZDate(DataAddr)^.Day := TS.Day;
                PZDate(DataAddr)^.IsNegative := TS.IsNegative;
              end;
    stTime: if not ZSysUtils.TryUniToTime(P, L, FConSettings^.ReadFormatSettings.TimeFormat, PZTime(DataAddr)^) then
              if ZSysUtils.TryUniToTimeStamp(P, L, FConSettings^.ReadFormatSettings.DateTimeFormat, TS) then begin
                PZTime(DataAddr)^ := PZTime(@TS.Hour)^;
                PZTime(DataAddr)^.IsNegative := False;
              end;
    stTimestamp: ZSysUtils.TryUniToTimeStamp(P, L, FConSettings^.ReadFormatSettings.DateTimeFormat, PZTimeStamp(DataAddr)^);
-Mark
Post Reply