Good day.
There is a task: to synchronize data from Active Directory via LDAP. Those. when you click on some button "Synchronization" in a program written in Delphi, update all existing and add new entries to the Oracle database.
As I understand it, for this in Oracle there is an operation MERGE INTO [...]. But in order not to load the database and not force it to parse 1500 queries each time, I would like to do all this using prepared (parametric) queries. I worked a little with this database, so questions immediately arose. I got a query like this (I can't say for sure yet, but it seems like it is):
MERGE INTO testtable USING( SELECT :field1_s field1, :field2_s field2, :field3_s field3, :field4_s field4 FROM dual ) data ON (data.field4 = testtable.field4) WHEN MATCHED THEN UPDATE SET testtable.field1 = data.field1, testtable.field2 = data.field2, testtable.field3 = data.field3 WHEN NOT MATCHED THEN INSERT VALUES(NULL, data.field1, NULL, data.field2, data.field3, NULL, data.field4)
On field4 in the testtable table there is a unique index and this field checks for the existence of this entry in the table.
In Delphi, I use ADO components (AdoConnection, AdoQuery) to work with both the Oracle database and Active Directory. I assign the parameters field1_s
, field2_s
, etc. to this query, and then set the values for the parameters in AdoQuery.Parameters.ParamByName('field1_s').Value
through AdoQuery.Parameters.ParamByName('field1_s').Value
. When I call the AdoQuery.ExecSQL procedure, Oracle gives me its error that not all the parameters were filled in, and specifically:
ORA-01008 not all variables bound
Already that only did not do. All that is achieved is another error: ORA-01036: illegal variable name/number
, which of course is no better :)
Now I would also like to note that the same parametric normal INSERT works fine and all data is entered into the table:
INSERT INTO testtable VALUES(NULL, :field1_s, NULL, :field2_s, :field3_s, NULL, :field4_s)
And therefore it begs the conclusion that the whole thing is in the SQL query. But that's what's with him - I'll never know! Maybe it's all about the SELECT subquery I use for MERGE? For example, the line can be guilty ... FROM dual
, which I added only because orakl swore on the absence of the keyword FROM? If so, how can you rewrite this query, so that Oracle inserts data not from the existing table, but new data that my program transmits?
The Oracle version on the server just can not say, but it seems - 11. At least, the client I use is version 11.
Tell me where to dig? Hope explained everything is clear. Thank you in advance.
UPD:
The Oracle version on the server is still 9.2. Parameters in the Delphi Bindu like this:
q_temp.SQL.Clear; q_temp.Close; q_temp.SQL.Add('MERGE INTO testtable USING ' + '(SELECT :field1_s, :field2_s, :field3_s, :field4_s FROM dual) ' + .... ); q_temp.ParamCheck := true; q_temp.Prepared := true; for i := 0 to 10 do begin q_temp.Parameters.ParamByName('field1_s').Value := ldapQuery.FieldByName('field1').AsString; q_temp.Parameters.ParamByName('field2_s').Value := ldapQuery.FieldByName('field2').AsString; q_temp.Parameters.ParamByName('field3_s').Value := ldapQuery.FieldByName('field3').AsString; q_temp.Parameters.ParamByName('field4_s').Value := outbuf; ldapQuery.Next; end;
I also tried to assign ftString types manually to parameters, but this did not change anything. Now I tried to make an identical non-parametric SQL query - everything works.
UPD2:
So far, in order not to transmit the entire request many times, I made the stored procedure and now call it. But it's all the same - not a solution. I wanted to see the server logs to really see what comes to it, but something did not work out. For example, the Toad utility swears at the absence of the dbms table (I have root rights). I also tried this little thing, but it doesn’t display requests and doesn’t work correctly. Can anyone know any good SQL profiler for Oracle, so that you can not look at the logs on the server (I have no access there), but on the client? For example, for MSSQL, this is SQL Server Profiler .