Why does my stored procedure not recognize my varchar string? - mysql

I currently have a stored procedure in MySQL called Admin_Emails, which accepts three parameters: siteID VARCHAR(20) categoryID INT approved INT
The siteID is always in the following format: s-xxx(x)-xxxxxx.
In the procedure I add the siteID to my query using the following:
IF(siteID IS NOT NULL)
THEN
SET #query = CONCAT(#query, " AND e.site_id = ", siteID);
END IF;
If I run the procedure (ex. CALL Admin_Emails('s-osp-123ABC', 2, 1) then I get the following error:
#1054 - Unknown column 's' in 'where clause'
The s is coming from the siteID string. I tried modifying my CONCAT statement to the following:
SET #query = CONCAT(#query, " AND e.site_id = ", "'" + siteID + "'");
which will not produce an error, but will give me results with siteID's that do not match the input. I purposely produced an error by excluding the AND in the query, and it was showing a 0 where the siteID should be:
#1064 - 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 'e.site_id = 0 AND e.category_id = 2 AND e.is_approved != 0' at line 20
I'm at a loss. I've tried searches for issues related to VARCHAR strings in stored procedures, but can't find similar situations. Is anyone aware of what I'm doing wrong here?
I didn't want to overload with the whole procedure, so I'm hoping that what I've provided here is enough, but if not I can produce more of my procedure.

why not
CONCAT(#query, " AND e.site_id = ", "'", siteID,"'");
Seems odd to try and + when concat() supports n values of string concat...
I think ++ is trying to do math which is resulting in the error.
Or you have an or limit at the end of the query and with the addition of and.... if the or doesn't have proper ()'s it could cause the issue of unexpected results.
Be warned if SiteID passed in isn't properly sanitized, you have SQL injection possibilities now.

Related

Unable to call a stored procedure

I'm learning mysql stored procedures and, as it turns out, I'm not so good at it for now. I want to create a stored procedure that selects some columns from different tables and, obviously, outputs the result. I have:
USE `usertable159`;
DROP procedure IF EXISTS `getDataFor`;
DELIMITER $$
USE `usertable159`$$
CREATE DEFINER=`michael`#`%` PROCEDURE `getDataFor`(IN COUNTRY VARCHAR(2), IN ASIN VARCHAR(20),IN FC VARCHAR(1))
BEGIN
SET #sql = "select p.price, p.sku, p.fulfillment_channel, GROUP_CONCAT(es.excludedSeller) excluded, r.excludeNonFeatured
FROM "+COUNTRY+"_products p
LEFT JOIN ("+COUNTRY+"_excludedSellers es, "+COUNTRY+"_excludeRules r)
ON p.seller_sku = es.seller_sku and p.seller_sku = r.seller_sku where p.ASIN = '" + ASIN + "' and p.fulfillment_channel = " + FC + ";
";
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
From all the errors I expected when writing this... the one I get is surprising to me:
Error Code: 1054. Unknown column 'de' in 'field list'
This is how I call it:
call getDataFor(de, B000LNHB8A, 2);
The IN parameter COUNTRY is not in the selected columns, how does it come?
I also tried calling it with
call getDataFor('de', 'B000LNHB8A', '2');
which results in
Error Code: 1064. 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 '2' at line 1
You have several problems:
1) You cannot concatenate strings with + in MySQL. You must use the CONCAT() built-in function.
2) Your LEFT JOIN syntax is incorrect. It should be LEFT JOIN x ON ... LEFT JOIN y ON ....
3) You must quote your arguments. It looks like you also tried that. You definitely need to do that.
You need to quote the call arguments:
call getDataFor('de', 'B000lNHB8A', 2)
^--^ ^----------^
Remember that any "string" that's not in quotes will be interpreted as a table/field name reference, NOT the value it represents.

stored procedure is issuing syntax error

I am trying to create a mysql stored procedure with phpmyadmin:
CREATE PROCEDURE AddTableColumn()
BEGIN
IF (SELECT COUNT (table_name)
FROM information_schema.tables
WHERE table_name IN ('authors', 'publishers') = 2 )
print 'specified tables exist...';
ELSE
print 'specified tables unavailable...';
END IF;
END​
above code is a snippet that should search information schema
for the availability of authors and publishers tables,
then proceed to add new column in each table if present.
the print statement was for debug purpose. when i clicked the
GO command, here's the error message :
MySQL said:
1064 - 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 'print 'avail...'; ELSE print 'unavail...'; END IF; END' at line
7.
what am i doing wrong ? i have even tried other code as a test,
all failing with the same error. code as simple as:
BEGIN
IF (6 > 4)
print 'greater';
ELSE
print 'lesser';
END IF;
END ​
all failed. any help will be appreciated.
'print' is not recognized in MySQL.
If you want to read back the output, just use a select in the SP.
Change part of your SP as below:
DECLARE found_status VARCHAR(255) DEFAULT NULL;
IF ....
SELECT 'specified tables exist...' INTO found_status;
ELSE
SELECT 'specified tables unavailable...' INTO found_status;
END IF;
SELECT found_status;

Lua & SQL Syntax Error

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.

Creating a database function within Magento for a module

I have a working module in Magento that is modeled after some custom code we use outside of our install. This module currently add 5 tables to the database to store info and I have extended the Admin to CRUD the info. The ultimate goal here is to move the majority of this custom programming into Magento.
Currently our custom code sits outside Magento and hits a separate database. This database has those same 5 tables, a stored procedure, and 4 functions. What I would like to do now is move the stored procedures and the functions into Magento's database and change the custom code to call all of it's data from Magento's db. However, I can't seem to figure out how the "CREATE FUNCTION" call should be set up for Magento to execute it properly.
The SQL I am using is:
DROP FUNCTION IF EXISTS {$this->getTable('fn_Get_HardinessZone')};
CREATE FUNCTION {$this->getTable('fn_Get_HardinessZone')}(IN ZipCode varchar()) RETURNS integer AS
DECLARE Result integer;
BEGIN
SELECT MAX(Zone) into Result
FROM AMI_zones
WHERE (Hfzip <= LEFT(ZipCode, 5)) AND (Htzip >= LEFT(ZipCode, 5));
if Result is null or Result < 1 or (Result > 11 and Result <> 99) Then
/*if the left most character is alpha, then set the zone to 98 for Canada*/
if Left(zipCode, 1) >= 'A' and LEFT(zipcode,1) <= 'Z' THEN
set result = 98;
else
set Result = 99;
End if;
END if;
RETURN Result;
END;
But this always generates the following error:
SQLSTATE[42000]: Syntax error or access violation: 1064 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 'IN ZipCode varchar()) RETURNS'
So what is the proper way to format a SQL call to be run in a module's install/update script to insert a function or stored procedure into Maganeto's database?
The problem is with your SQL statement:
You have an error in your SQL syntax; check the manual ...
for the right syntax to use near
'IN ZipCode varchar()) RETURNS'
I would recommend running the SQL through PhpMyAdmin or on the command line until you get it right, then run it through Magento. This man page describes the syntax of CREATE FUNCTION: http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html. When testing stored procedures /functions in the mysql client (or PhpMyAdmin) be sure to change the delimiter so that the semicolons in your function body are interpreted correctly.
The below SQL worked for me. The things I changed from your original statement are:
IN is not allowed in function declarations (IN ZipCode varchar())
I was required to explicitly state length of the varchar
The DECLARE belongs inside the function
I am guessing that your function is DETERMINISTIC, meaning it will always produce the same results for the same input parameters. If this is not the case, remove DETERMINISTIC from the RETURNS line
Give this a shot:
DROP FUNCTION IF EXISTS {$this->getTable('fn_Get_HardinessZone')};
CREATE FUNCTION {$this->getTable('fn_Get_HardinessZone')} (ZipCode VARCHAR(15))
RETURNS INTEGER DETERMINISTIC
BEGIN
DECLARE result INTEGER;
SELECT MAX(Zone) INTO result
FROM AMI_zones
WHERE (Hfzip <= LEFT(ZipCode, 5)) AND (Htzip >= LEFT(ZipCode, 5));
IF result IS NULL OR result < 1 OR (result > 11 AND result <> 99) THEN
/* if the left most character is alpha, then set the zone to 98 for Canada */
IF LEFT(ZipCode, 1) >= 'A' AND LEFT(ZipCode, 1) <= 'Z' THEN
SET result = 98;
ELSE
SET result = 99;
END IF;
END IF;
RETURN result;
END;

Stored procedures written in MySQL 5.5.8 don't work in 5.1

I have some stored procedures and a trigger that work great in MySQL 5.5.8 but for some reason don't work in 5.1. The error descriptions aren't enough for me to figure out the problem. Here is the code and the errors.
CREATE PROCEDURE `cg_getMatchingContent`(
MatchTerm VARCHAR(255),
MaxResults INT)
BEGIN
SELECT * FROM (
SELECT t.*, INSTR(t.`Title`,MatchTerm) as Pos
FROM cg_content t ) c
WHERE Pos>0 ORDER BY Pos LIMIT 0, MaxResults;
END
Error: 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 'MaxResults' at line 8
DELIMITER ;;
CREATE TRIGGER `cg`.`cg_content_UrlDup_ConstTrig`
BEFORE INSERT ON `cg`.`cg_content`
FOR EACH ROW
Begin
DECLARE errorString VARCHAR(500);
DECLARE insert_error CONDITION FOR SQLSTATE '99001';
IF new.Url = '' THEN
SET errorString = CONCAT('Url cannot be blank
Title: ' , new.Title);
SIGNAL insert_error
SET MESSAGE_TEXT=errorString;
END if;
IF Exists(SELECT id FROM cg.cg_content WHERE Url=new.Url) THEN
SET errorString = CONCAT('Url is not unique
Title: ' , new.Title , '
Url: ' + new.Url);
SIGNAL insert_error
SET MESSAGE_TEXT=errorString;
End if;
End ;;
Error: 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 'insert_error
SET MESSAGE_TEXT=errorString;END if;IF ' at line 10
From the docs:
Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables as of MySQL 5.5.6.
5.1 does not support variables in LIMIT and OFFSET.
The second one is easy to figure, hard to fix. SIGNAL and RESIGNAL commands were introduced in MySQL 5.5. You can't convert it easily to 5.1. One way to do it, would be to run a query that errors. For example a SELECT from a non-existent table.