2014-12-23 76 views
0

我正在尝试编写一个prodecure,更新给定列名中的值,其中用户id等于给定的用户ID。动态MySQL更新声明

_strong_1是一个包含列名称的变量,例如:'category_1'。

SELECT COLUMN_NAME FROM information_schema.`COLUMNS` C 
WHERE table_name = 'subscribers_preferences' AND COLUMN_NAME LIKE _strong_1 INTO @columns; 

SET @table = 'subscribers_preferences'; 
SET @s = CONCAT('UPDATE ',@table,' SET ', @columns = 1); 

PREPARE stmt FROM @s; 
EXECUTE stmt; 

'SET @s ='语句内有错误。我可以通过一个简单的SELECT语句来处理它,但UPDATE很棘手。

在此先感谢。

+0

'@ columns'列出了多少列?如果你有多个,那么你需要在每列的末尾添加'= 1'。否则,你有'column1,column2 = 1'这是不正确的语法,它应该是'column1 = 1,column2 = 1'。 – Taryn

+0

“@columns = 1”语句正确吗? – aldux

回答

1

你需要把= 1放在引号中。

SET @s = CONCAT('UPDATE ',@table,' SET ', @columns, ' = 1'); 

否则,你与1比较@columns,并连接要么10(可能总是0,因为我怀疑你有一个名为1列)的SQL,这是创建无效SQL。

请注意,上述代码只会更新一列。如果@columns应该保存3列,则需要在设置它的查询中使用GROUP_CONCAT

SELECT GROUP_CONCAT(CONCAT(column_name, ' = 1')) AS @columns 
FROM information_schema.columns 
WHERE table_name = 'subscribers_preferences' and column_name LIKE _strong_1; 
SET @table = 'subscribers_preferences'; 
SET @s = CONCAT('UPDATE ',@table,' SET ', @columns); 

我怀疑你还需要一个WHERE条款添加到该SQL因此,它只是更新为给定的ID行。按照目前的写法,它将更新所有行。

事实上,你需要写这样的查询,这表明你的数据不正常的正常化。而不是将每个首选项选项放在不同的列中,它们应该是表格的不同行,关键字是(user_id, setting_name)

+0

嗯,我正在寻找一个解决方案来更新20个单独类别列中的3个特定类别列。我能做到的唯一方法是创建一个类别列,但这会导致用户拥有20行数据PER用户......也许这就是解决方案,但效果并不高效 – wUmpage

+1

我已更新答案展示如何使用匹配模式的3列进行操作。 – Barmar

+0

如果您有适当的索引,它是有效的。每当你发现自己写动态SQL时,你应该强烈地认为你的设计有问题。您通常应该在数据中搜索字段,而不是元数据。 – Barmar