I'm trying both of these ways to run a SQL query with Lua using the GMod mysqloo library.
Each query is complaining about the line with the EXISTS() having an SQL syntax error.
local SQL6 = [[INSERT INTO accounts(UniqueID,Money)
VALUES(]]..UniqueID..[[,]]..StartingCash..[[)
WHERE NOT EXISTS(SELECT 0 FROM accounts WHERE UniqueID=]]..UniqueID..[[)]]
local SQL7 = [[IF Not EXISTS (SELECT * FROM accounts WHERE UniqueID=']]..UniqueID..[[')
BEGIN
INSERT INTO accounts(UniqueID,Money)
VALUES(]]..UniqueID..[[,]]..StartingCash..[[)
END
ELSE
BEGIN
SELECT * FROM accounts WHERE UniqueID=]]..UniqueID..[[
END]]
I don't know SQL but it seems that:
you need quotes around UniqueID in line 3 and 11, as in line 4.
you probably need a space or newline before the last END.
Related
In Sybase ASE and Microsoft SQL Server, you can use procedural SQL (control flow statements like IF/ELSE and WHILE, declaring and setting lexical variables, and so on) in one-off SQL statement batches, like so:
-- from https://msdn.microsoft.com/en-us/library/ms182587.aspx
DECLARE #Number INTEGER;
SET #Number = 50;
IF #Number > 100
SELECT 'The number is large.' AS large;
ELSE
BEGIN
IF #Number < 10
SELECT 'The number is small.' AS small;
ELSE
SELECT 'The number is medium.' AS medium;
END;
You can send this code directly to SQL Server, without preparing it or putting it in a stored procedure, and SQL Server will send back a table with a single tuple and column, with the value "The number is medium."
From what I can tell, in MySQL, procedural SQL code is restricted to appearing only within stored procedure definitions (CREATE PROCEDURE or CREATE FUNCTION statements):
mysql> delimiter //
mysql> if 32 = 32 then
-> select 'yes';
-> else
-> select 'no';
-> end if;
-> //
ERROR 1064 (42000): You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near
'if 32 = 32 then
select 'yes';
else
select 'no';
end if'
at line 1
Is this impression correct?
Yes, you are correct. Lots of constructs are only valid inside stored functions, like if. It even says so in the manual.
"The IF statement for stored programs implements a basic conditional construct."
However, the same result can be achieved using another approach, with the function if
select if(32 = 32, 'yes', 'no');
sqlfiddle
MySQL v5.6.17. I am getting an incorrect syntax error on the first line when stepping through this (generic error 1064 - 'Script line: 33 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'declare x int' at line 1
"). I have looked at examples of other do-whiles but step through execution of this code hasn't even made it that far. Very puzzled. I would also appreciate any suggestions on whether this do-while method is most efficient. Essentially I need to loop through split_col_table thousands of rows looking at DelimitedCol column which hold delimited values, and remove each delimited value into a separate ROW into report, then I am deleting that previous value and the delimiter from split_col_table until there are no delimiters left. At the end I will make a final pass to get the remainder of the values out of DelimitedCol in split_col_table.
Code relevant to the loop:
declare x int;
set x = select count(*) from split_col_table where DelimitedCol like '%;%';
while x > 0 DO
INSERT INTO report (SELECT id, val1,LEFT(DelimitedCol,LOCATE(';',DelimitedCol)-1) FROM split_col_table where DelimitedCol like '%;%');
UPDATE split_col_table SET DelimitedCol = RIGHT(DelimitedCol, LENGTH(DelimitedCol)- LOCATE(';',DelimitedCol)) where DelimitedCol > '';
#repeat until no more ';' in split_col_table
set x = select count(*) from split_col_table where DelimitedCol like '%;%';
end while;
I'm using SQL Server 2008 R2. I have a stored procedure to append from two source tables to a master table while calculating some of the columns. Before I can append from source 1 to the master table I have to update column Service_Element so that downstream procedures can join tables correctly.
After I update I want to create some QA, so that if the columns didn't update correctly, it will stop the procedure (this cause me and my team to rerun our entire process last month because the error was not caught until after we ran everything)
Below is the code I have so far.
declare #secount as int
set #secount = (
select COUNT(*)
from (
select
datepart(year, ReportingMonth) as full_year,
Service_Element,
sum(Quantity) as amount
from tbl_VolumeImport
where (Service_Element like '%Windows%' or Service_Element like '%Linux%' )
and datepart(year, ReportingMonth) = '2014'
group by datepart(year, ReportingMonth), Service_Element) as E)
select case
when #secount = 0 then print 'no errors' else print 'can not proceed'
end as Error
This is the error that I get:
Msg 156, Level 15, State 1, Line 11
Incorrect syntax near the keyword 'print'.
Msg 102, Level 15, State 1, Line 12
Incorrect syntax near 'end'.
Also I would like to change the else to RETURN so that it stops the rest of the procedure.
Thanks
Try this instead.
if #secount = 0
begin
print 'no errors'
end
else
begin
print 'can not proceed'
return
end
more code....
I am a MySQL-noob and today I tried to setup a MySQL call which is more than 5 lines long. I keep getting syntax errors which I try to fix for hours, but I don't have a clue what the problem is. Here is the code:
USE myDatabase;
DELIMITER //
CREATE PROCEDURE MYPROC()
BEGIN
SET #ID = 1;
SET #maxID = 3;
CREATE TEMPORARY TABLE resultTable(v DOUBLE, ttc DOUBLE);
WHILE (#ID < #maxID) DO
INSERT partTable1.v, partTable2.ttc
INTO
resultTable
FROM
(SELECT * FROM
(((SELECT time_sec, v FROM speedTable WHERE (trip_id = #ID)) as partTable1)
INNER JOIN
((SELECT time_sec, ttc FROM sightsTable WHERE (trip_id = #ID)) as partTable2) ON
(0.04 > abs(partTable1.time_sec - partTable2.time_sec)))
);
SET #ID := #ID + 1;
END WHILE;
END //
DELIMITER;
CALL MYPROC();
SELECT * FROM resultTable LIMIT 100;
Is there anything obvious that needs to be corrected?
Update1: Added semicolon to the "CREATE.."-statement, now first three statements are OK.
Update2: Added 3 more semicolons!
Update3: Followed the suggestion to make it a function + separate function call. Error message changed!
Update4: I fixed the issues mentioned in the two answers. Still something wrong there. See updated code above and error message below.
Updated error message:
ERROR 1064 (42000) at line 4: You have an error in your SQL syntax; check the ma
nual that corresponds to your MySQL server version for the right syntax to use n
ear ' partTable2.ttc
INTO
resultTable
FROM
(SELECT * FROM
(((SELE' at line 11
Kind Regards,
Theo
Flow control statements, of which WHILE is one, can only be used within a stored procedure, but you are attempting to use it as a plain query via the console.
If you absolutely must take this path (using mysql instead of an application language), create a store procedure with the code you want, then call it.
Creating the procedure would look like this:
DELIMITER //
CREATE PROCEDURE MYPROC()
BEGIN
WHILE (#ID < #maxID) DO
SET #partTable1 = (SELECT time_sec, v FROM speedTable WHERE (trip_id = #ID));
SET #partTable2 = (SELECT time_sec, ttc FROM sightsTable WHERE (trip_id = #ID));
INSERT v, ttc INTO resultTable FROM
(#partTable1 INNER JOIN #partTable2 ON
(0.04 > abs(partTable1.time_sec - partTable2.time_sec)));
SET #ID := #ID + 1;
END WHILE;
END//
DELIMITER ;
Then to call it:
CALL MYPROC();
See this SQLFiddle of a simplified version of this working.
Note that you do have one syntax error:
#ID = #ID + 1; -- incorrect syntax
SET #ID := #ID + 1; -- correct
Still some syntactic problems and functionality problems...
You can't use WHILE in SQL scripts. You can use WHILE only in the body of a stored routine. See http://dev.mysql.com/doc/refman/5.6/en/flow-control-statements.html
You can't use SET to assign multiple columns to a scalar. MySQL doesn't support relation-valued variables, only scalar variables. See http://dev.mysql.com/doc/refman/5.6/en/set-statement.html
You can INSERT from the results of a query with a join, but the query must be introduced with SELECT. See http://dev.mysql.com/doc/refman/5.6/en/insert-select.html
You can't use session variables as the names of tables. You would have to use a prepared statement. See http://dev.mysql.com/doc/refman/5.6/en/prepare.html But that opens a whole different can of worms, and doing it wrong can be a security vulnerability (see http://xkcd.com/327). I wouldn't recommend you start using prepared statements as a self-described MySQL-noob.
This problem is probably simpler than you're making it. You don't need a temporary table, and you don't need to read the results one row at a time.
Here's an example that I think does what you intend:
USE myDatabase
SET #ID = 1;
SET #maxID = 3;
SELECT sp.v, si.ttc
FROM speedTable AS sp
INNER JOIN sightsTable AS si
ON (sp.trip_id = si.trip_id AND 0.04 > ABS(sp.time_sec - si.time_sec))
WHERE sp.trip_id BETWEEN #ID AND #maxID;
I'm used to MS sql so working with mySql is sure to throw some syntax error at me that is bound to slow me down. I have the following:
declare #expensesSum DOUBLE
select #expensesSum = sum(expenseAmount) from bondsaverdb.expenses
insert into bondsaverdb.expenses
select '6','Extracash',(income - #expensesSum) from bondsaverdb.income where userName ='Dean'
The error I'm getting says:
syntax error near declare #expensesSum
Must be the way I'm declaring the variable??
Thanks in advance!
MySQL does not require (or even allow, apparently) you to declare variables, and as far as I know it will treat all objects, variables included, as strings -- so they cannot be typed in t his way. Anyway, this should work:
SET #expensesSum = (SELECT SUM(expenseAmount) FROM bondsaverdb.expenses);
INSERT INTO
bondsaverdb.expenses
SELECT
'6', 'Extracash', (income - #expensesSum)
FROM
bondsaverdb.income
WHERE
userName = 'Dean'
I'm also not sure what that '6' is for .. if that's an auto increment ID you should omit it from the INSERT altogether (and specify the other columns to write to) or leave it NULL.
MySQL is very different to SQL Server; you don't declare variables generally
SET #expensesSum = (select #expensesSum = sum(expenseAmount) from bondsaverdb.expenses);
insert into bondsaverdb.expenses
select '6','Extracash',(income - #expensesSum) from bondsaverdb.income where userName ='Dean';