Oracle protocol and string params
Posted: 16.10.2020, 21:00
Hi All!
I'm using some input and output params in a PL/SQL anonymous block and I'm seeing some strange issues. It appears that ptInput params that are strings need to be ftWideString type, but ptOutput params need to be ftString type (or they come out as incorrectly encoded strings with embedded #0 (utf16 as ansi basically.)) Using ptInputOutput params are also affected (and I don't think there's a workaround since they have to be ftWideString on input and ftString on output.) Here's a console program that shows the issue. It won't error, but will show the incorrect encoding of "ParamOut". Uncomment the indicated line to see the other error. I'm thinking that this is a bug, but wanted to check here before creating a ticket.
Thanks!
-Mark
I'm using some input and output params in a PL/SQL anonymous block and I'm seeing some strange issues. It appears that ptInput params that are strings need to be ftWideString type, but ptOutput params need to be ftString type (or they come out as incorrectly encoded strings with embedded #0 (utf16 as ansi basically.)) Using ptInputOutput params are also affected (and I don't think there's a workaround since they have to be ftWideString on input and ftString on output.) Here's a console program that shows the issue. It won't error, but will show the incorrect encoding of "ParamOut". Uncomment the indicated line to see the other error. I'm thinking that this is a bug, but wanted to check here before creating a ticket.
Code: Select all
program ZeosParamTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Classes,
Data.DB,
ZDbcIntfs, ZConnection, ZDataset;
var
ZConn: TZConnection;
ZQuery: TZQuery;
Param: TParam;
begin
try
ZConn := TZConnection.Create(nil);
ZConn.Protocol := 'oracle';
ZConn.User := 'scott';
ZConn.Password := 'tiger';
ZConn.Database := '//192.168.1.100/orcl.local';
ZConn.LibraryLocation := 'C:\Oracle\19\32\oci.dll';
ZConn.AutoCommit := False;
ZConn.TransactIsolationLevel := tiReadCommitted;
ZConn.Connect;
ZQuery := TZQuery.Create(nil);
ZQuery.Connection := ZConn;
// Note that we have to double the :: on := to escape it from the parser.
ZQuery.SQL.Text := 'BEGIN :ParamOut ::= ''Input: ''|| :ParamIn; END;';
Param := ZQuery.ParamByName('ParamIn');
Param.ParamType := ptInput;
Param.AsString := 'Testing'; // Sets datatype to ftWideString which works
// Param.DataType := ftString; // UnComment this to see the error.
Param := ZQuery.ParamByName('ParamOut');
Param.ParamType := ptInputOutput;
// Param.DataType := ftString; // Correct output
Param.DataType := ftWideString; // Looks like utf-16 as ansi.
ZQuery.ExecSQL;
// Write out the param values.
for var i := 0 to ZQuery.Params.Count - 1 do
begin
Param := ZQuery.Params[i];
Writeln(Param.DisplayName + ': ' + Param.AsString);
end;
Writeln('Done');
ZConn.Disconnect;
ZQuery.Free;
ZConn.Free;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Write('Press Enter to quit...');
ReadLn;
end.
-Mark