I've met the problem when using execute immediate in Teradata.
SET str_sql = 'UPDATE TABLE
SET COLA = 0';
EXECUTE IMMEDIATE str_sql;
The above code works fine.
SET str_sql = 'UPDATE TABLE
SET COLA = 0,
COLB = ''test''';
EXECUTE IMMEDIATE str_sql;
The above code with string returns error.
The following is the error message:
Executed as Single statement. Failed [3706 : 42000] Table:Syntax error: expected something between a string or a Unicode character literal and the word 'test'.
Elapsed time = 00:00:00.212
STATEMENT 1: CALL failed.
Anyone know how to invoke the execute immediate with String in the sql?
Thanks!
Frank Liu
The problem might be on quotation. Instead of this
SET str_sql = 'UPDATE TABLE
SET COLA = 0,
COLB = ''test''';
EXECUTE IMMEDIATE str_sql;
Use double quotation.
SET str_sql = 'UPDATE TABLE
SET COLA = 0,
COLB = 'test'';
EXECUTE IMMEDIATE str_sql;
Related
Good Day all,
I am writing a program to build a report where I build the SQL statement to insert selected records into a file and after that insert I would like to do a simple update on the file to change a select fields in some records.
The problem is that after the insert is run, anytime I try to update the file I get a Record or File in use error.
I have tried updating it programatically with sqlrpgle and with I/O read and set functions and I have even tried just updating the file in STRSQL after I run the program and I all come to the same error.
I suspect I am not closing something properly but I am not sure what.
Code is as follows
// Assign SQL Query
sqlstmt = 'insert into jallib/orhsrpt ('+
'oacctd, oacmp, oaord, oacust, o8type, ' +
'o8text, o8date, o8time ) ' +
'select oacctd, oacmp, oaord, oacust, ' +
'o8type, o8text, o8date, o8time ' +
'from r50files.vcohead ' +
'join r50files.vcopkct ' +
'on oacmp = o8cmp and oaord = o8ord ' +
'where oacmp = 1 ' +
'and o8type not in (' +
'''C'',''a'',''H'',''E'',''F'', '+
'''A'',''1'',''N'',''M'') ' +
'and oacctd = ' + curdate +
' order by oaord, o8time ';
// Prepare for multiple sql statements
exec sql
Set Option Commit = *NONE;
// Clear output file before executing SQL
exec sql
Delete from jallib/orhsrpt;
if sqlcode < *zeros;
errmsg = 'Delete of file failed';
endif;
// Execute SQL Insert statement
exec sql prepare sqlsel from :sqlstmt;
exec sql execute sqlsel;
if sqlcode < *zeros;
errmsg = 'Insert of file failed';
endif;
// Update file data
exec sql
Set Option clossqlcsr = *ENDMOD;
exec sql
Update jallib/orhsrpt
set o8text = 'Order Invoiced'
where o8type = 'I'
The error from STRSQL is as follows
Row or object ORHSRPT in JALLIB type *FILE in use.
The quick answer is that the insert is not closed because your module hasn't ended according to the Set Option you specified. However, the correct answer here is that there is no reason for you to be using dynamic SQL statements at all. They are slower and more error prone in general and you run into issues like this one. You should instead use a regular embedded SQL statement as below:
exec sql
set option commit = *NONE;
// Clear output file before executing SQL
exec sql
delete from jallib/orhsrpt;
if sqlstate <> *zeros;
errmsg = 'Delete of file failed';
endif;
exec sql
insert into jallib/orhsrpt (
oacctd, oacmp, oaord, oacust,
o8type, o8text, o8date, o8time )
select oacctd, oacmp, oaord, oacust, o8type,
o8text, o8date, o8time
from r50files.vcohead join r50files.vcopkct
on oacmp = o8cmp and oaord = o8ord
where oacmp = 1 and o8type not in (
'C','a','H','E','F', 'A','1','N','M') and
oacctd = :curdate
order by oaord, o8time;
exec sql
update jallib/orhsrpt
set o8text = 'Order Invoiced'
where o8type = 'I'
This is better practice and should solve your issue.
I have a simple update statement that refuese to execute when passed from VB.NET (probably will after 10 minutes or so... haven't waited that long). But it executes in 1 sec from Oracle SQL Developer.
There are 67000 rows in table1
strQuery = "UPDATE table1 SET TYPE2 = TYPE2 || ', 5_badTag' WHERE LARGE = 'NO' AND ROUND = 'NO'"
SqlInsert = strQuery
cmdOleDbCommand = New Oracle.DataAccess.Client.OracleCommand(SqlInsert, dataAccessConn)
adpterODA.InsertCommand = cmdOleDbCommand
adpterODA.InsertCommand.ExecuteNonQuery()
Is there an open transaction on this table from another session (e.g. your SQL Developer)?
I am new to Vbscript (3 days to be precise),
I am connecting my script to SQL Server and playing around with databases. I have connected successfully
Now here's what I want to do:
I want to store the value of SELECT COUNT(*) FROM TABLE_A in a variable to be used in VBscript.
This SQL query returns the number of rows in table and it is an integer, but how do I return it and save in a variable?
I tried this:
Dim VARX
SET VARX = connection.execute("SELECT COUNT(*) FROM TABLE_A")
So now VARX should contain the number of rows of TABLE_A.
But this is a wrong way I know. And of course It posts an error "TYPE Mismatch:". Please guide me!
Try something like this :
Dim rs, varx
SET rs = connection.execute("SELECT COUNT(*) FROM TABLE_A")
varx = rs(0).value
Not my field of expertise actually, here are some references :
http://www.tek-tips.com/viewthread.cfm?qid=1632757
VBScript - Retrieving a Scalar Value From a Stored Procedure on SQL Server 2008
Here is the final code which worked:
...
Set Recordset=CreateObject("ADODB.Recordset")
ConnString="DRIVER={SQL Server};SERVER=PCX\SQLEXPRESS;UID=sa;PWD=password;DATABASE=testdb"
Dim SQL_Rows, NoOfRows
SQL_Rows = "SELECT Count (*) from Table_A"
Recordset.open SQL_Rows,ConnString
NoOfRows = Recordset(0).value
Recordset.close
MsgBox NoOfRows
Now Message Box shows the number of rows in table_A
I am trying to check if a specific username exists within a database (Access) using SQL. If I use only letter or string characters the code works fine but when I use numbers as in the example below even though I insert them as a string I get the error:
"Could not convert variant of type (Null) into type (OleStr)"
DataModule.Query.Active := False;
sQuery := 'SELECT * FROM Login WHERE Username = "31"';
DataModule.Query.SQL.Text := sQuery;
DataModule.Query.Active := True;
I dont know what I'm doing wrong.
edit:
The debugger gives the error just after the if line in the following code
if UpperCase(DataModule.Query['Username']) = sUsername then
begin
if DataModule.Query['Password'] = sPassword then
begin
bPass := True;
end
[Solved]
Thank you all for the advice I got it working!
You should use Query.FieldByName('Password').AsString (same for Username field) to eliminate any NULL issues. .AsString will convert db NULLs to Delphi empty string ''.
After you open your query you need to test if there are any records before you actually test username/password logic.
Note: You don't need to check the Username again because if the query returned results there is a match and that user exists in your table:
bPass := False;
if not DataModule.Query.IsEmpty then
if DataModule.Query.FieldByName('Password').AsString = sPassword then
begin
bPass := True;
end
As already mentioned you better use parameterized query. or at least use QuotedStr to avoid SQL injection. e.g.:
sQuery := 'SELECT * FROM Login WHERE Username = ' + QuotedStr('31');
A parameterized query should look like this:
sQuery := 'SELECT * FROM Login WHERE Username = :Username';
DataModule.Query.SQL.Text := sQuery;
DataModule.Query.ParamByName('Username').Value := '31';
Assume that we have this SQL statement:
UPDATE article SET saison='12E', mode='ECH', client='SAS', WHERE ID='3448fe81-1bec-e011-8546-001f3ccf8f20'
This SQL statement is generated by concatenated strings like this:
// saison change
procedure TarticleEditForm.saisonComboChange(Sender: TObject);
begin
SQLQuery := SQLQuery + 'saison=''' + saisonCombo.Text + ''',';
end;
// client change
procedure TarticleEditForm.clientComboChange(Sender: TObject);
begin
SQLQuery := SQLQuery + 'client=''' + clientCombo.Text + ''',';
end;
.
.
.
As you see, there is a comma before "WHERE" clause. How can I remove the last comma to have the correct statement:
UPDATE article SET saison='12E', mode='ECH', client='SAS' WHERE ID='3448fe81-1bec-e011-8546-001f3ccf8f20'
RMQ: the number of comma is not fixe, it can be 1, 2, 5...
thank you.
The solution is replacing ", WHERE" by "WHERE"
SQLQuery := StringReplace(SQLQuery , ', WHERE', 'WHERE', [rfReplaceAll]);
I am using this to trace every change in HISTORY Table.
Thank you all.
Rather than concatenating the changes to the SQL string as they happen, store them in a collection and build you SQL string after all the options have been evaluated.
Then you will know how many fields are going to be changed and build the statement correctly. Of course this will require you to store not only the value but also the name of the fild being changed:
[pseudo code]
for i=0 to fields_changed.count {
sql = sql + fields_changed(i).field_name + " = " + fields_changed(i).new_value
if i < fields_changed.count {
sql = sql + ", "
}
}
sql = sql + " WHERE ..."
EDIT: The other option you have is to simply perform a string replace on , WHERE with WHERE just before executing the statement; since the word 'where' is a reserved word and should not occur more than once in your SQL statement. This may be the simpler solution even if it feels like a bit of a hack.
another option is to reduce the length of the string by 1 character before appending the WHERE clause.