2010-05-02 12 views
23

Próbuję przekazać nazwę tabeli do mojego mysql procedura przechowywana aby skorzystać z tej sproc, aby wybrać się z różnych tabel, ale to nie działa ...użyć zmiennej o nazwie tabeli w mysql sproc

to co i "Usiłuję:

CREATE PROCEDURE `usp_SelectFromTables`(
IN TableName varchar(100) 
) 
BEGIN 
     SELECT * FROM @TableName; 
END 

ja również próbowałem go w/o znaku @ i że po prostu mówi mi, że TableName nie istnieje ... co wiem :)

Odpowiedz

12

zależy DBMS, ale notacja zwykle wymaga dynamicznego SQL i uruchamia problem polegający na zwracaniu wartości z f Nałożenie zależy od wejść, kiedy jest wykonywane. Daje to conniptions systemu. Zgodnie z ogólną zasadą (a więc prawdopodobnie podlegającą wyjątkom), system DBMS nie zezwala na użycie symboli zastępczych dla parametrów strukturalnych zapytania, takich jak nazwy tabel lub nazwy kolumn; pozwalają one tylko określić wartości, takie jak wartości kolumn.

Niektóre DBMS mają obsługę procedur przechowywanych, które pozwolą ci zbudować ciąg SQL, a następnie pracować z tym, używając "przygotowania" lub "wykonania natychmiast" lub podobnych operacji. Zauważ jednak, że nagle jesteś podatny na ataki typu SQL injection - ktoś, kto może wykonać twoją procedurę, jest wtedy w stanie kontrolować, po części, co SQL wykonuje.

44
SET @cname:='jello'; 
SET @vname:='dwb'; 
SET @sql_text = concat('select concept_id,concept_name,',@vname,' from enc2.concept a JOIN enc2.ratings b USING(concept_id) where concept_name like (''%',@cname,'%'') and 3 is not null order by 3 asc'); 

PREPARE stmt FROM @sql_text; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 
+0

WOW, co za bril dobry sposób! –

12

Dodatkowy bit, który przysporzył mi problemów.

Chciałem ustawić nazwę tabeli i pole dynamicznie w zapytaniu, tak jak pytał @kyle, ale chciałem również zapisać wynik tego zapytania do zmiennej @a w zapytaniu.

Zamiast umieszczać zmienną @a w literę concat, należy uwzględnić ją jako część tekstu ciągu.

delimiter // 

CREATE PROCEDURE removeProcessed(table_name VARCHAR(255), keyField VARCHAR(255), maxId INT, num_rows INT) 

BEGIN 
    SET @table_name = table_name; 
    SET @keyField = keyField; 
    SET @maxId = maxId; 
    SET @num_rows = num_rows; 

    SET @sql_text1 = concat('SELECT MIN(',@keyField,') INTO @a FROM ',@table_name); 
    PREPARE stmt1 FROM @sql_text1; 
    EXECUTE stmt1; 
    DEALLOCATE PREPARE stmt1; 

    loop_label: LOOP 
    SET @sql_text2 = concat('SELECT ',@keyField,' INTO @z FROM ',@table_name,' WHERE ',@keyField,' >= ',@a,' ORDER BY ',@keyField,' LIMIT ',@num_rows,',1'); 
    PREPARE stmt2 FROM @sql_text2; 
    EXECUTE stmt2; 
    DEALLOCATE PREPARE stmt2; 

    ...Additional looping code... 

    END LOOP; 
END 
// 

delimiter ; 

Więc w @sql_text1 przypisać wynik zapytania do @a obrębie łańcucha przy użyciu:

') INTO @a FROM '

Następnie w @sql_text2 użytku @a jako rzeczywistej zmiennej:

,' WHERE ',@keyField,' >= ', @a ,' ORDER BY '

Powiązane problemy