簡體   English   中英

MYSQL變量-SET @var

[英]MYSQL variables - SET @var

我正在嘗試創建一個將分析表並刪除重復項的MySQL代碼段(重復項基於兩個字段而不是整個記錄)

當我對查詢中的變量進行硬編碼時,我有以下代碼可以工作,但是當我將它們取出並放入變量中時,卻得到了MySQL錯誤,以下是腳本:

SET @tblname = 'mytable';
SET @fieldname = 'myfield';
SET @concat1 = 'checkfield1';
SET @concat2 = 'checkfield2';

ALTER TABLE @tblname ADD `tmpcheck` VARCHAR( 255 ) NOT NULL;

UPDATE @tblname SET `tmpcheck` = CONCAT(@concat1,'-',@concat2);

CREATE TEMPORARY TABLE `tmp_table` (
`tmpfield` VARCHAR( 100 ) NOT NULL
) ENGINE = MYISAM ;

INSERT INTO `tmp_table` (`tmpfield`) SELECT @fieldname FROM @tblname GROUP BY `tmpcheck` HAVING ( COUNT(`tmpcheck`) > 1 );

DELETE FROM @tblname WHERE @fieldname IN (SELECT `tmpfield` FROM `tmp_table`);

ALTER TABLE @tblname DROP `tmpcheck`;

我收到以下錯誤:

#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 '@tblname ADD `tmpcheck` VARCHAR( 255 ) NOT NULL' at line 1 

這是因為我不能為表名使用變量嗎? 還有什么可能是錯誤的,或者我將如何解決這個問題。

這是因為我不能為表名使用變量嗎?

是的,或者其他模式名稱(如列)。 字符串變量只能在MySQL需要'引號的字符串的地方使用。

如果您確實需要執行此操作,則可以使用“動態SQL”:將整個查詢創建為字符串,然后將@tblname連接到字符串中,然后使用EXECUTE執行操作 這很丑陋,如果您不小心會導致SQL注入,因此,如果有其他選擇,請避免使用。

從mytable GROUP BY tmpcheck選擇myfield HAVING(COUNT( tmpcheck )> 1)

對我來說這似乎有問題。 除非myfieldmyfield具有功能依賴性(因為tmpcheck不是主鍵,所以不能對tmpcheck依賴), tmpcheck這不是有效的ANSI SQL。 MySQL將讓您擺脫它,但是您要說的是“對於共享tmpcheck值的tmpcheck ,從該行中隨機選擇一行的fieldname ,以便以后刪除”。 那真的是你想要的嗎? 我希望您想刪除所有重復項之一。

通常,您不需要這種復雜的過程即可刪除重復項。 只需使用DELETE-join:

DELETE my0
FROM mytable AS my0
JOIN mytable AS my1
    ON my1.checkfield1=my0.checkfield1 AND my1.checkfield2=my0.checkfield2
    AND my1.id>my0.id;

這是假設一個id字段是可排序且UNIQUE以便您可以決定保留哪一行(此處是id最高的那一行)。 myfield可能就是那個領域,但是我無法從上下文中分辨出來。

為表名使用變量確實是非法的。 您必須將SQL生成為字符串,並使用准備好的語句功能來執行它。

我使用了兩個答案的組合:

SET @tblname = 'myTable';
SET @idfield = 'myPrimaryKey';
SET @check1 = 'field1';
SET @check2 = 'field2';

SET @q1 = CONCAT('DELETE my0 FROM `',@tblname, '` AS my0 JOIN `',@tblname, '` AS my1 ON my1.',@check1,' = my0.',@check1,' AND my1.',@check2,' = my0.',@check2,' AND my1.',@idfield,' > my0.',@idfield,'');
PREPARE stmt1 FROM @q1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM