2011-12-02 2 views
1

변수를 저장 프로 시저 내에서 테이블 이름으로 사용하려고 시도하고 실제 테이블 이름 대신 문자열 리터럴로 사용하고 있습니다. 왜 이런거야? 이 작업을 수행하는 또 다른 방법이 있습니까 (PHP에서 수행하는 것 외에)?저장 프로 시저에서 테이블 이름으로 변수를 사용할 수없는 이유는 무엇입니까?

DROP PROCEDURE IF EXISTS settonull; 

DELIMITER // 

CREATE PROCEDURE settonull() 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE _tablename VARCHAR(255); 
    DECLARE _columnname VARCHAR(255); 
    DECLARE cur1 CURSOR FOR SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS table_name, COLUMN_NAME AS column_name FROM information_schema.COLUMNS WHERE IS_NULLABLE = 'YES' AND TABLE_SCHEMA = 'blip_notify' AND table_name = 'notify_queue' LIMIT 1; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

    OPEN cur1; 

    read_loop: LOOP 
    FETCH cur1 INTO _tablename, _columnname; 

    IF done THEN 
     LEAVE read_loop; 
    END IF; 

    UPDATE _tablename SET _columnname = NULL WHERE LENGTH(TRIM(_columnname)) = 0; 

    END LOOP; 

    CLOSE cur1; 
END// 

DELIMITER ; 

CALL settonull(); 

출력 :

당신은 동적 SQL을 사용할 필요가
0 row(s) affected, 1 warning(s) 

Execution Time : 0 sec 
Transfer Time : 1.094 sec 
Total Time  : 1.095 sec 

Note Code : 1305 
PROCEDURE settonull does not exist 
--------------------------------------------------- 

0 row(s) affected 

Execution Time : 0.002 sec 
Transfer Time : 1.011 sec 
Total Time  : 1.014 sec 
--------------------------------------------------- 

Query: call settonull() 

Error Code: 1146 
Table 'blip_notify._tablename' doesn't exist 

Execution Time : 0 sec 
Transfer Time : 0 sec 
Total Time  : 0.003 sec 
--------------------------------------------------- 
+0

http://stackoverflow.com/questions/8362245/updating-empty-string-to-null-for-entire-database를 해결하기 위해이 도구를 사용해 보았습니다. – hafichuk

답변

6

. 나중에.

SET @s = CONCAT('UPDATE ', _tablename, ' SET ', _columnname, ' = NULL WHERE LENGTH(TRIM(', _columnname, ')) = 0'); 
PREPARE stmt FROM @s; 
EXECUTE stmt; 
3

변수는 테이블 식별자가 아닌 문자열 값 (또는 다른 데이터 유형)을 포함합니다.

SQL 쿼리의 일부를 문자열로 연결 한 다음 해당 문자열을 SQL 문으로 PREPARE and EXECUTE으로 연결하면 저장 프로 시저에서 원하는 작업을 수행 할 수 있습니다.

그러나 FWIW, 나는 PHP에서 그걸 할 것입니다.

mysql_real_escape_string()과 같은 이스케이프 기능이 테이블 이름에 도움이되지 않기 때문에 SQL 쿼리에 동적으로 테이블 이름을 추가 할 때 SQL 주입 취약점에주의하십시오. 내 프레젠테이션 SQL Injection Myths and Fallacies에서 "화이트리스트 맵"에 대한 내 솔루션을 참조하십시오.

관련 문제