Delphi, error :"Access violation at address xxxxxxxx. Read of address yyyyyyyy", at AdoQuery.SQL.Text:=''' - sql

"Access violation at address xxxxxxxx. Read of address yyyyyyyy"
On this project i have more than 200 procedures like that, but only this procedure gets error (only windows xp)..
Procedure than have error :
Procedure TfMain.CreateNewDocument(p_money_direction,p_status,p_base:integer);
begin
With fMain.ADOTemp do
Begin
SQL.Clear;
SQL.Text:='INSERT INTO documents '+
'(document_date,fk_id_status,money_direction,'+
'paid,addition,saving,fk_id_base,fk_id_user)'+
'VALUES '+
'(CONVERT(DATE,:pdocument_date,103),:pfk_id_status,'+
':pmoney_direction,0,0,0,:pfk_id_base,:pfk_id_user)';
Parameters.ParamByName('pdocument_date').Value:=Date;
Parameters.ParamByName('pfk_id_status').Value:=p_status;
Parameters.ParamByName('pmoney_direction').Value:=p_money_direction;
Parameters.ParamByName('pfk_id_base').Value:=p_base;
Parameters.ParamByName('pfk_id_user').Value:=fMain.ApplicationVariablers.user_id;
ExecSQL;
End;
end;
Error at :
SQL.Text:='INSERT INTO documents '+
'(document_date,fk_id_status,money_direction,'+
'paid,addition,saving,fk_id_base,fk_id_user)'+
'VALUES '+
'(CONVERT(DATE,:pdocument_date,103),:pfk_id_status,'+
':pmoney_direction,0,0,0,:pfk_id_base,:pfk_id_user)';
Debuingging process, error at line 1907 :

I fix the problem like that
Procedure TfMain.CreateNewDocument(p_money_direction,p_id_status,p_id_base:integer);
Var
ADOTemp:TAdoQuery;
begin
ADOTemp:=TADOQuery.Create(nil);
ADOTemp.Connection:=fMain.ADOConnection;
With ADOTemp do
Begin
SQL.Clear;
SQL.Add('INSERT INTO documents');
SQL.Add('(document_date,fk_id_status,money_direction,');
SQL.Add('paid,addition,saving,fk_id_base,fk_id_user)');
SQL.Add('VALUES ');
SQL.Add('(CONVERT(DATE,GETDATE(),103),:pfk_id_status,:pmoney_direction,');
SQL.Add('0,0,0,'+IntToStr(p_id_base)+',:pfk_id_user)');
Parameters.ParamByName('pfk_id_status').Value:=p_id_status;
Parameters.ParamByName('pmoney_direction').Value:=p_money_direction;
//Parameters.ParamByName('p').Value:=p_id_base;
Parameters.ParamByName('pfk_id_user').Value:=fMain.ApplicationVariablers.user_id;
ExecSQL;
End;
end;
I removed Parameters.ParamByName('p').Value:=p_id_base; and it worked
http://oi43.tinypic.com/dvotxx.jpg
But it is not good solition

As first, change assigment for text property using "add" insthead .text.
Using text is not good. some year ago I've issue uisng text property for a complex sql statement.
Also, I suggest you:
FORGET WITH STATEMENT.
Each time I works on code using "with" I spend (waste) more more time to understand code.
With fMain.ADOTemp do
Begin
AdoTemp.SQL.Clear;
AdoTemp.SQL.Add( ' INSERT INTO documents ');
AdoTemp.SQL.Add( ' (document_date,fk_id_status,money_direction, ');
....

Related

Is possible to set filter option in SMDBGrid to CaseInsensitive?

I have SMDBGrid component with show filter bar option set to true, but filter just working in case-sensitive mode
1.Try with lower case
2.Try with upper case
I have tried to insert the code in SMDBgrid.pas like this
procedure TSMDBGrid.ApplyFilter;
var
TempCol: Integer;
begin
if (eoFilterAutoApply in ExOptions) then
begin
TempCol := LeftCol;
BeginUpdate;
try
if DataLink.Active then
begin
DataLink.DataSet.CheckBrowseMode;
DataLink.DataSet.Filtered := False;
DataLink.DataSet.OnFilterRecord := nil;
DataLink.DataSet.OnFilterRecord := OnFilterRecord;
DataLink.DataSet.FilterOptions := [foCaseInsensitive]; <-- this the inserted code
DataLink.DataSet.Filtered := not FilterIsEmpty();//True;
end;
finally
LeftCol := TempCol;
EndUpdate;
end;
end;
if Assigned(OnFilterChanged) then
OnFilterChanged(Self);
end;
But no luck, Is posible filter the record ignoring the case?
PS:
I use Delphi 2009
You may use the OnAccentStringConvert event to transform the value for filter in column before compare:
begin
Result := UpperCase(S)
end;
Looks like I cope with this problem too. Trying to find any solution for Delphi XE 10.3 community edition and wrote to author of SMDBGrid and he found workaround.
Please use SQL ADOQuery as follows.
SELECT UPPER(field) FROM your_table
then use event OnAccentStringConvert and uppercase S String as follows:
function TYourFormName.DBGrridNameAccentStringConvert(Sender: TObject; const S: string): string;
begin
Result := UpperCase(S)
end;
This works very ugly, but at least works. Or you may just create filter by yourself for every table.

PL/SQL ORA06550 error in an update statement

The following is a proc code that I have written . I am getting a syntax error in the block marked from (A) to (B) , namely , ORA06550, saying SQL command not ended properly.
If I eliminate the line l.ban4_upd ='UPDATED' there are no more of nay error messages.
I don't know how to correct it . Hoping for your help and thanks in advance
DECLARE
dummy_BAN4 VARCHAR2(30);
dummy_bank_acc_num VARCHAR2(20);
CURSOR c_customers is
SELECT BAN4,Bank_acc_num FROM Test_Table ;
BEGIN
OPEN c_customers;
LOOP
FETCH c_customers into dummy_BAN4 , dummy_bank_acc_num;
IF c_customers%notfound THEN
update Test_Table chs Set
chs.error_msg ='No such record found in DB '
where bank_acc_num =dummy_bank_acc_num;
END IF;
update Transact_ord2 l Set.........................(A)
l.ban4_upd ='UPDATED'
l.x_account_number =dummy_BAN4
where X_account_number =dummy_bank_acc_num; ..........(B)
you are missing , between the fields you set:
update Transact_ord2
Set ban4_upd = 'UPDATED',
x_account_number = dummy_BAN4
where X_account_number = dummy_bank_acc_num;
Check this

Delphi 2007 Adoquery Parameters not working

ADOQuerySelect.Close;
ADOQuerySelect.SQL.Add(' AND (дата_заказа between #'+dat+'# and #'+da+'#)');
if ComboBox6.Text <> '' then
begin
ADOQuerySelect.Parameters.ParamByName('Name').Value := ComboBox6.Text ;
ADOQuerySelect.SQL.Add(' AND (Наименование = :Name)');
end;
ADOQuerySelect.Open;
I use Delphi 2007, MS Access. And i dont now how work with parameters. On this code, i have error: parameter Name not found. I tried many other variants of code, but they all not working. I add parameter Name via GUI with datatype ftstring;
Changing SQL in your code clears the existing parameters, so there's no parameter called 'Name' at the time you try to set its value. You then create the Name parameter, but it's too late.
Change the order of your statements:
ADOQuerySelect.Close;
ADOQuerySelect.SQL.Add(' AND (дата_заказа between #'+dat+'# and #'+da+'#)');
if ComboBox6.Text <> '' then
begin
ADOQuerySelect.SQL.Add(' AND (Наименование = :Name)');
ADOQuerySelect.Parameters.ParamByName('Name').Value := ComboBox6.Text ;
end;
ADOQuerySelect.Open;
You should be using parameters for all your replacements, BTW. Let the database driver handle conversions and date formats and quoting values and all of that for you.
In the object inspector ADOQuerySelect should have 'Name' among list of parameters.
You can also use the following code to create the parameter 'Name':
with ADOQuerySelect.Parameters.AddParameter do
begin
Name := 'Name';
DataType := ftString;
end;

How to display the value of a variable used in a PL/SQL block in the log file of a batch file? And Arrays?

Basically I'm using a batch file to run a .sql file on Windows Task Scheduler. The batch file generates a log file that displays all the put_lines. I now want to also see the value assigned to the variable: v_chks_dm, but couldn't figure out a way to do it. Tried the get_line statement but failed... Does anyone know how to do it?
thanks!
This is what's in the batch file:
echo off
echo ****************************>>C:\output.log
sqlplus userid/password#csdpro #V:\CONDITION_TEST.sql>>C:\output.log
Here's the .sql file
declare
v_chks_dm number;
begin
Select /*+parallel (a,4)*/ count(distinct a.src_table) into v_chks_dm
from hcr_dm.hcr_dm_fact a;
dbms_output.put_line('v_chkt_dm value assigned');
-- dbms_output.get_line(v_chks_dm);
if.... then... else.... end if;
end;
One more question... what if the variable is an array? I have something like this, but got an error says ORA-06533: Subscript beyond count. The number of values in the array usually varies from 0 to 10, but could be more. Thanks!
declare
type v_chks_array is varray(10) of varchar2(50);
arrSRCs v_chks_array;
begin
arrSRCs :=v_chks_array();
arrSRCs.EXTEND(10);
Select /*+parallel (a,4)*/ distinct a.src_table BULK collect into arrSRCs
from hcr_dm.hcr_dm_fact a;
dbms_output.put_line(arrSRCs(10));
end;
dbms_output.put_line('v_chkt_dm value = ' || v_chkt_dm);
or, better
dbms_output.put_line('v_chkt_dm value = ' || to_char(v_chkt_dm, '<number format>'));
You can choose appropriate number formats in documentation.

More than 4000 chars gives string literal too long error on oracle

I am currently using oci8 driver on Codeigniter.
While updating a field that will have more than 4000 chars, I was given a error :
ORA-01704: string literal too long
So, going through few blogs, I got this:
declare
vClobVal varchar2(32767) := 'long text'
begin
update FMS_K_OFFICEWISE_LETTER set FKOL_LETTER_BODY=vClobVal
where FKOL_OFFICEWISE_LETTER_ID=240;
end;
This worked for me when fired at Toad.
Now, I created a stored procedure and compiled as :
CREATE OR REPLACE PROCEDURE FMIS3.UPDATE_LETTER_BODY ( body_text IN FMS_K_OFFICEWISE_LETTER.FKOL_LETTER_BODY%type,condition_id in FMS_K_OFFICEWISE_LETTER.FKOL_OFFICEWISE_LETTER_ID%type)IS
begin
update FMS_K_OFFICEWISE_LETTER set FKOL_LETTER_BODY=body_text
end;
and this does not work for more than 4000 chars again. Can't I define the size of varchar2 as it gave me error. Any suggestions ?
Even tried using PDO by binding parameters, works only when the string is of size less than 4000 chars :(
$conn = new PDO("oci:dbname=".$this->db->hostname,$this->db->username,$this->db->password);
$params = array(
':body_text' => "Long String"
);
$sth = $conn->prepare("update FMS_K_OFFICEWISE_LETTER set FKOL_LETTER_BODY = :body_text
where FKOL_OFFICEWISE_LETTER_ID=241");
$sth->execute($params) or die('error occured');
Check this out :
declare
vClobVal varchar2(32767) := 'long text'
begin
update FMS_K_OFFICEWISE_LETTER set FKOL_LETTER_BODY=vClobVal
where FKOL_OFFICEWISE_LETTER_ID=240;
end;
Are you sure this is not supported ?
In PL/SQL, a VARCHAR2 can have 32767 bytes, but in SQL only 4000 bytes. Therefore the BEGIN ... END; block worked, as it is PL/SQL, and the procedure didn't, as it is SQL.
varchar2 has a limit of 4000 chars. Use CLOB instead.