When i run the following code in mysql workbench im getting the above mentioned error Pls do help
# IF p_Name is not null THEN
# SET m_sql = m_sql +' Name=''' + p_Name + ''' and ';
# END IF;
If p_ReligionID is not null THEN
SET m_sql = m_sql + '" ReligionId= "' + 'CAST(p_ReligionID AS CHAR(30))' + 'and';
END IF;
If p_CasteID is not null THEN
SET m_sql = m_sql + '" CasteId= "' + 'CAST(p_CasteID AS CHAR(30))' + 'and';
END IF;
If p_CountryID is not null THEN
SET m_sql=m_sql+ '" Countryid= "' + 'CAST(p_CountryID AS CHAR(30))' + 'and';
END IF;
If p_MotherTongueID is not null THEN
SET m_sql=m_sql+'" MotherTongueID= "' + 'CAST(p_MotherTongueID AS CHAR(30))' + 'and';
END IF;
Assuming m_sql is valid on entry and at least one of the conditions passes, the final statement ends with an 'and'. That's not valid SQL in any dialect I know. Then you have to deal with what appears to be extraneous quoting.
I'd suggest the ANDs be inserted at the beginning of the follow-on condition
If p_ReligionID is not null THEN
SET m_sql = m_sql + ' and ReligionId = ' + 'CAST(p_ReligionID AS CHAR(30))';
END IF;
(I'm a SQL Server person, so the particulars of MySql's procedural language are beyond my ken)
Related
I am building this simple query using following code:
FDQuery1.SQL.Text := 'INSERT INTO album SET customer_id=' + Chr(39) + IntToStr(CustomerID) + Chr(39) + ',lab_id=' + Chr(39) + IntToStr(LabID) + Chr(39) +
', album_name_c = ' + Chr(39) + ProjectFolderName + Chr(39) +
', album_name_s = ' + Chr(39) + ProjectFolderNameOnServer + Chr(39) +
' ,album_size=' + Chr(39) + txtAlbumSize.Text + Chr(39) +
', album_paper=' + Chr(39) + txtPaperFinish.Text + Chr(39) +
', album_cover=' + Chr(39) + txtCover.Text + Chr(39) +
', album_binding=' + Chr(39) + txtBinding.Text + Chr(39) +
', album_coating=' + Chr(39) + txtCoating.Text + Chr(39) +
', starts_from=' + Chr(39) + BoolToStr(chkRight.Checked) + Chr(39) +
'; SELECT LAST_INSERT_ID() AS RecID;';
But when I call FDQuery1.OpenOrExecute I get error message as stated in subject of this post.
Current query length is around 299 characters.
I read somewhere on internet that the Query length should be less than 255 characters, so I have also tried to shorten the query but keep its length below 255 characters.
But still I get the same error message.
What wrong am I doing here please guide me.
TIA
Yogi Yang
Ok finally I found the actual problem and solved it...
It so happens that the dumb FireDAC's Query component does not support query in the format stated in original post. I had to build traditional Insert query as per SQL norms.
Though query with SET keyword is supported by MySQL and I have been using it in my PHP projects so there is not question of the query being wrong.
Ok what I did with suggestion/help of other developers in another forum was build a parameterized query and use it like below:
FDQuery1.SQL.Text := 'INSERT INTO album(customer_id, album_name_c, album_name_s, album_size, album_paper, album_cover, album_binding, album_coating, starts_from, total_files, lab_id, upload_date, album_uploaded) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);';
FDQuery1.Params.Items[0].AsInteger := CustomerID;
FDQuery1.Params.Items[1].AsString := ProjectFolderName;
FDQuery1.Params.Items[2].AsString := ProjectFolderNameOnServer;
FDQuery1.Params.Items[3].AsString := AlbumSize;
FDQuery1.Params.Items[4].AsString := PaperFinish;
FDQuery1.Params.Items[5].AsString := Cover;
FDQuery1.Params.Items[6].AsString := Binding;
FDQuery1.Params.Items[7].AsString := Coating;
if chkLeft.Checked then
FDQuery1.Params.Items[8].AsString := '1'
else
FDQuery1.Params.Items[8].AsString := '0';
if chkRight.Checked then
FDQuery1.Params.Items[8].AsString := '2'
else
FDQuery1.Params.Items[8].AsString := '0';
FDQuery1.Params.Items[9].AsInteger := lstFiles.Count;
FDQuery1.Params.Items[10].AsInteger := LabID;
FDQuery1.Params.Items[11].AsDate := Now;
FDQuery1.Params.Items[12].AsString := '1';
FDQuery1.Execute;
Thanks to this parameterized query I did not have to add single quotes to varchar and data fields data using Chr(39).
I hope this will help other developers solve similar problems that they may face.
Regards,
Yogi Yang
My print statement fails each time and so does my exec, anytime I try to run this statement it just tells me command completed successfully. I added the print statement to try to see what was actually being executed, but I am still mind-blown on this. Can someone here please help me?
Shouldn't the Print statement at least show me what I am trying to run? If I print each variable individually before trying to run the update it shows the correct value, so I can only assume it is something way wrong with my update statement?
Declare #fulldata varchar(30), #rsi varchar(50), #employeename varchar(50), #email varchar(50), #rsi2 varchar(50), #email2 varchar(50),
#rsiID varchar(50), #calldate datetime, #calltime datetime, #orderdate datetime, #email3 varchar(50), #uniqueID int, #sql varchar(max)
Set #fullData = 'tvdb'
Set #rsi = 'Alphabet'
Set #employeename = 'Mike Jones'
Set #email = '123abc#gmail.com'
Set #rsi2 = 'Broccoli'
Set #email2 = 'abc123#gmail.com'
Set #rsiID = 'alt16bc'
Set #calldate = '06/15/2015'
Set #calltime = '12:15:00'
Set #orderdate = '06/16/2015'
Set #email3 = 'pineapple1841#gmail.com'
Set #uniqueID = 172855
Set #sql =
'update '+#fulldata+' '
+ 'set rsi = COALESCE('''+#rsi+''',''''), '
+ 'employeename = COALESCE('''+#employeename+''',''''), '
+ 'email = COALESCE('''+#email+''',''''), '
+ 'rsi2 = COALESCE('''+#rsi2+''',''''), '
+ 'email2 = COALESCE('''+#email2+''',''''), '
+ 'rsiID = COALESCE('''+#rsiID+''',''''), '
+ 'calldate = COALESCE('''+CAST(#calldate As Varchar)+''',''''), '
+ 'calltime = COALESCE('''+CAST(#calltime As Varchar)+''',''''), '
+ 'orderdate = COALESCE('''+CAST(#orderdate As Varchar)+''',''''), '
+ 'email3 = COALESCE('''+#email3+''','''') '
+ 'where uniqueID = '+CAST(#uniqueID As Varchar)+' and '+CAST(#uniqueID As Varchar)+' > 0 '
Print #sql
exec (#sql)
EDIT ---
If I try to insert my statements into a table to check it is null. Which leads me to why is #sql not being assigned?
Insert Into #SqlStatement (sql12) VALUES (#sql)
Select * FROM #SqlStatement
Are you sure you have all lines included here? and you can run it without error?
At least your don't have declaration of #sql.
Even you declare the #sql, this line will give you error:
Set uniqueID = 172855
It should be
Set #uniqueID = 172855
Without assigning values to #uniqueID, your whole #sql is be NULL and print will generate NO output.
update tvdb set rsi = COALESCE('Alphabet',''), employeename = COALESCE('Mike Jones',''), email = COALESCE('123abc#gmail.com',''), rsi2 = COALESCE('Broccoli',''), email2 = COALESCE('abc123#gmail.com',''), rsiID = COALESCE('alt16bc',''), calldate = COALESCE('Jun 15 2015 12:00AM',''), calltime = COALESCE('Jan 1 1900 12:15PM',''), orderdate = COALESCE('Jun 16 2015 12:00AM',''), email3 = COALESCE('pineapple1841#gmail.com','') where uniqueID = 172855 and 172855 > 0
Msg 208, Level 16, State 1, Line 1
Invalid object name 'tvdb'.
To debug your code, you can comment out some lines like:
Set #sql =
'update '+#fulldata+' '
+ 'set rsi = COALESCE('''+#rsi+''',''''), '
---+ 'employeename = COALESCE('''+#employeename+''',''''), '
----+ 'email = COALESCE('''+#email+''',''''), '
----+ 'rsi2 = COALESCE('''+#rsi2+''',''''), '
----+ 'email2 = COALESCE('''+#email2+''',''''), '
----+ 'rsiID = COALESCE('''+#rsiID+''',''''), '
----+ 'calldate = COALESCE('''+CAST(#calldate As Varchar)+''',''''), '
----+ 'calltime = COALESCE('''+CAST(#calltime As Varchar)+''',''''), '
----+ 'orderdate = COALESCE('''+CAST(#orderdate As Varchar)+''',''''), '
----+ 'email3 = COALESCE('''+#email3+''','''') '
----+ 'where uniqueID = '+CAST(#uniqueID As Varchar)+' and '+CAST(#uniqueID As Varchar)+' > 0 '
Print #sql
exec (#sql)
and uncomment one line a time until you find the problematic line.
To catch values and make sure you have a non-null #sql, you need use the COALESCE this way:
Set #sql =
'update '+#fulldata+' ' ...
+ 'email = '''+COALESCE(#email,'')+''','
My request payload from the client javascript/angular
active: 1
appId: "asdf"
description: "asdf"
from: "06/16/2015"
name: "gdsfg"
to: "06/18/2015"
Node.js code is
var query = "SET #start = '" + request.body.from + "'; \
SET #end = '" + request.body.to + "'; \
SET #event_id = " + rows.insertId + "; \
CALL day(#start, #end, #event_id);";
Error return is
{ [Error: ER_TRUNCATED_WRONG_VALUE: Incorrect date value: '06/16/2015' for column 'start' at row 2]
code: 'ER_TRUNCATED_WRONG_VALUE',
errno: 1292,
sqlState: '22007',
index: 3 }
stored procedure:
(in essence it takes the from and to dates and create the number of rows based on the difference).
CREATE DEFINER=`root`#`localhost` PROCEDURE `day`(start DATE, end DATE, event_id INT)
BEGIN
WHILE start <= end DO
INSERT INTO day(date, event_id) VALUES(start, event_id);
SET start = start + 1;
END WHILE;
END
Question:
not sure what's causing the error, can anyone please help
Edit - query output
SET #start = '06/16/2015'; SET #end = '06/18/2015'; SET #event_id = 3; CALL day(#start, #end, #event_id);
I am guessing that date is stored as a date. But start is not, possibly it is just an integer that looks like a date.
If so, this will fix your problem:
WHILE start <= end DO
INSERT INTO day(date, event_id) VALUES(start, event_id);
SET start = date_add(#tart, interval 1 day);
END WHILE;
EDIT:
That is not the problem. The problem is in the calling code. So try:
var query = "SET #start = str_to_date('" + request.body.from + "', '%m/%d/%Y'); \
SET #end = str_to_date('" + request.body.to + "', '%m/%d/%Y'); \
SET #event_id = " + rows.insertId + "; \
CALL day(#start, #end, #event_id);";
you should use 'yyyy-mm-dd' format instead of 'mm/dd/yyyy' in your query. as your procedure parameters are date type
your query should be like this
SET #start = '2015-06-16'; SET #end = '2015-06-18'; SET #event_id = 3; CALL day(#start, #end, #event_id);
I am trying to add the group_concat function to hsqldb so that I can properly test a query as a unit/integration test. The query works fine in mysql, so I need it to work in hsqldb (hopefully).
// GROUP_CONCAT
jdbcTemplate.update("DROP FUNCTION GROUP_CONCAT IF EXISTS;");
jdbcTemplate.update(
"create aggregate function group_concat(in val varchar(100), in flag boolean, inout buffer varchar(1000), inout counter int) " +
" returns varchar(1000) " +
" contains sql " +
"begin atomic " +
" if flag then" +
" return buffer;" +
" else" +
" if val is null then return null; end if;" +
" if buffer is null then set buffer = ''; end if;" +
" if counter is null then set counter = 0; end if;" +
" if counter > 0 then set buffer = buffer || ','; end if;" +
" set buffer = buffer + val;" +
" set counter = counter + 1;" +
" return null;" +
" end if;" +
"end;"
);
Adding this aggregation function solves most of the problem. It will correctly behave like mysql's group_concat. However, what it won't do is let me use the distinct keyword like this:
group_concat(distinct column)
Is there any way to factor in the distinct keyword? Or do I rewrite the query to avoid the distinct keyword altogether?
HSQLDB has built-in GROUP_CONCAT and accepts DISTINCT.
http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_aggregate_funcs
At the moment you cannot add DISTINCT to a user-defined aggregate function, but this looks like an interesting feature to allow in the future.
I am writing code to script CREATE TABLE statements for all tables across all databases on a server.The code below will work for a specific database. Would like some ideas on how to modify it, so it can script table schema for all the tables.
select 'create table [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END
from sysobjects so
cross apply
(SELECT
' ['+column_name+'] ' +
data_type + case data_type
when 'sql_variant' then ''
when 'text' then ''
when 'decimal' then '(' + cast(numeric_precision_radix as varchar) + ', ' + cast(numeric_scale as varchar) + ')'
else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') end + ' ' +
case when exists (
select id from syscolumns
where object_name(id)=so.name
and name=column_name
and columnproperty(id,name,'IsIdentity') = 1
) then
'IDENTITY(' +
cast(ident_seed(so.name) as varchar) + ',' +
cast(ident_incr(so.name) as varchar) + ')'
else ''
end + ' ' +
(case when IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' +
case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', '
from information_schema.columns where table_name = so.name
order by ordinal_position
FOR XML PATH('')) o (list)
left join
information_schema.table_constraints tc
on tc.Table_name = so.Name
AND tc.Constraint_Type = 'PRIMARY KEY'
cross apply
(select '[' + Column_Name + '], '
FROM information_schema.key_column_usage kcu
WHERE kcu.Constraint_Name = tc.Constraint_Name
ORDER BY
ORDINAL_POSITION
FOR XML PATH('')) j (list)
where xtype = 'U'
AND name NOT IN ('dtproperties')
Since you seem determined on TSQL, a quick and dirty solution would be to use the (undocumented) sp_foreachdb stored procedure. That will give you the name of every database on the sql instance, so you would just USE each database in turn and run TSQL that you posted (after escaping all the single qoutes in it).
Heres a shortened example:
EXECUTE sp_msforeachdb 'USE [?]
select ''create table ['' + so.name + ''] ''
from sysobjects so
-- the rest of your escaped TSQL goes here...
-- then finish with a closing quote:
'