我最近遇到了一个问题,我一直在将一串逗号分隔值发送到存储过程中。我的问题是,当我在PHP中执行我的存储过程时,它会像上面那样用引号上传值;
CALL `rankingInformation`('145', '5', '', '37,38,39,40,41')
未能添加引号会使MySQL将其解释为额外参数。
但是,在查询方面的WHERE IN中它的意思是,它的意思是这样格式化
'37', '38', '39', '40', '41'
以下是查询,有人能发现我能做的任何事吗?这就是我现在所做的。
CREATE DEFINER = `root`@` localhost` PROCEDURE` rankingInformation`(IN` surveyId` INT, IN` filterCounting` INT, IN` survey_filter_id` INT, IN` question_limit` TEXT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Gathers all the ranking information for a given ID'
BEGIN
DECLARE sfi int(2);
DECLARE ql TEXT;
IF(survey_filter_id = '') THEN
SET sfi = (SELECT sf2.survey_filter_id FROM survey_filters AS sf2 WHERE sf2.survey_id = 145 AND sf2.survey_filter_id IS NOT NULL LIMIT 1);
ELSE
SET sfi = survey_filter_id;
END IF;
SELECT
COUNT( * ) AS total, CONCAT(su.first_name, ' ', su.last_name) as full_name, sf.survey_filter_id, sf.survey_filter_name, qa.question_id, su.temp_group_1 AS department
FROM questions_answers AS qa
INNER JOIN survey_users AS su ON su.survey_users_id = qa.survey_users_id_answer
INNER JOIN survey_filters AS sf ON sf.survey_id = surveyId
WHERE qa.survey_id = surveyId
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
AND sf.survey_filter_id = sfi
GROUP BY qa.survey_users_id_answer
HAVING total > filterCounting
ORDER BY total DESC;
END
splitAndTranslate 这是我发现的一个功能,这意味着要完成这项工作,我不确定我是不是很远。
CREATE DEFINER=`root`@`localhost` FUNCTION `splitAndTranslate`(`str` TEXT, `delim` VARCHAR(1))
RETURNS text CHARSET utf8
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Fixes all Where IN issues'
BEGIN
DECLARE i INT DEFAULT 0; -- total number of delimiters
DECLARE ctr INT DEFAULT 0; -- counter for the loop
DECLARE str_len INT; -- string length,self explanatory
DECLARE out_str text DEFAULT ''; -- return string holder
DECLARE temp_str text DEFAULT ''; -- temporary string holder
DECLARE temp_val VARCHAR(255) DEFAULT ''; -- temporary string holder for query
-- get length
SET str_len=LENGTH(str);
SET i = (LENGTH(str)-LENGTH(REPLACE(str, delim, '')))/LENGTH(delim) + 1;
-- get total number delimeters and add 1
-- add 1 since total separated values are 1 more than the number of delimiters
-- start of while loop
WHILE(ctr<i) DO
-- add 1 to the counter, which will also be used to get the value of the string
SET ctr=ctr+1;
-- get value separated by delimiter using ctr as the index
SET temp_str = REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delim, ctr), LENGTH(SUBSTRING_INDEX(str, delim,ctr - 1)) + 1), delim, '');
-- query real value and insert into temporary value holder, temp_str contains the exploded ID
#SELECT ImageFileName INTO temp_val FROM custombu_roomassets_images WHERE ImageID=temp_str;
-- concat real value into output string separated by delimiter
SET out_str=CONCAT(out_str, temp_val, ',');
END WHILE;
-- end of while loop
-- trim delimiter from end of string
SET out_str=TRIM(TRAILING delim FROM out_str);
RETURN(out_str); -- return
END
答案 0 :(得分:1)
你用FIND_IN_SET做了什么?基于spencer7593的答案,如果你替换它应该有效:
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
带
AND FIND_IN_SET(qa.question_id, question_limit)>0
答案 1 :(得分:0)
在SQL IN比较的上下文中,字符串值中的逗号不被解释为SQL文本。您的查询基本上是以下形式:
AND qa.question_id IN ('some,long,string,value')
字符串中的任何逗号字符都只是数据;只是属于字符串的字符。这实际上与等于比较相同。
MySQL FIND_IN_SET
函数可能是您进行所需比较的一种方式。
http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_find-in-set
答案 2 :(得分:0)
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
将这些行代替上面的行
AND (qa.question_id = question_limit
OR qa.question_id LIKE CONCAT(question_limit,',%')
OR qa.question_id LIKE CONCAT('%,',question_limit,',%')
OR qa.question_id LIKE CONCAT('%,',question_limit))
然后您不再需要splitAndTranslate函数。 。