Как использовать динамический SQL для объявления имени столбца, полученного из имени таблицы? - PullRequest
0 голосов
/ 09 августа 2010

Опираясь на Ответ Тони на этот вопрос :

Если я хочу сделать что-то подобное,

CREATE PROCEDURE A(tab IN VARCHAR2) IS
tab.col_name <column> --static declaration (column name always remains the same)
BEGIN
   EXECUTE IMMEDIATE 'INSERT INTO ' || tab(col_name) || 'VALUES(123)';
END A;

Как использовать динамический SQL в приведенном выше случае?

1 Ответ

4 голосов
/ 09 августа 2010

В этом примере передается имя таблицы и имя столбца:

CREATE PROCEDURE A
  ( tab IN VARCHAR2
  , col_name IN VARCHAR2
  ) IS
BEGIN
   EXECUTE IMMEDIATE 'INSERT INTO ' || tab || '(' || col_name || ') VALUES(123)';
END A;

Вы должны понимать, что все после EXECUTE IMMEDIATE должно быть строкой, содержащей некоторый допустимый SQL. Хороший способ убедиться в этом - установить его в переменную и вывести на экран:

CREATE PROCEDURE A
  ( tab IN VARCHAR2
  , col_name IN VARCHAR2
  ) IS
   v_sql VARCHAR2(2000);
BEGIN
   v_sql := 'INSERT INTO ' || tab || '(' || col_name || ') VALUES(123)';
   DBMS_OUTPUT.PUT_LINE('SQL='||v_sql);
   EXECUTE IMMEDIATE v_sql;
END A;

Это должно отобразить что-то вроде следующего в SQL Plus:

SQL = INSERT INTO mytable (mycolumn) ЗНАЧЕНИЯ (123)

(при условии, что сервер включен).

РЕДАКТИРОВАТЬ : Поскольку вы хотите, чтобы имя столбца было локальной переменной, которая всегда имеет одно и то же значение, это можно сделать так:

CREATE PROCEDURE A (tab IN VARCHAR2)
IS
   col_name VARCHAR2(30) := 'MYCOLUMN';
   v_sql VARCHAR2(2000);
BEGIN
   v_sql := 'INSERT INTO ' || tab || '(' || col_name || ') VALUES(123)';
   DBMS_OUTPUT.PUT_LINE('SQL='||v_sql);
   EXECUTE IMMEDIATE v_sql;
END A;
...