我想为rowtype的字段赋值,但我不知道该怎么做。
假设我的数据库中有一个表 X 。
假设我还有以下变量
a
(X%ROWTYPE
),代表表格X的一行b
(VARCHAR2
),包含表格X的列名称c
(VARCHAR2
),包含我要存储在a.b中的内容 我想做什么:类似a.b := c
。
我想出了类似的东西:
EXECUTE IMMEDIATE 'SELECT '|| c || ' INTO a.' || b || ' FROM DUAL';
显然,这不是正确的方法。我收到 ORA-0095:缺少关键字错误。
任何人都可以帮我吗?
以下是完整的代码:
DECLARE
tRow MyTable%ROWTYPE;
col_name VARCHAR(10) := 'Length';
nValue NUMBER(12,4) := 0.001;
dynamic_request VARCHAR(300);
BEGIN
dynamic_request := 'SELECT '|| nValue || ' INTO tRow.' || col_name || ' FROM DUAL';
EXECUTE IMMEDIATE dynamic_request;
END;
答案 0 :(得分:2)
好的,我解决了!
简答:使用全局变量可以解决问题
回答开发
让我们考虑两个关于动态PL / SQL块的事实(即,作为字符串写入的PL / SQL块,通过EXECUTE IMMEDIATE
语句执行)
[1] 创建动态PLSQL块时,不存在变量范围。我的意思是,如果你做这样的事情:
CREATE OR REPLACE PROCEDURE DynamicVariableAssignment(
theString IN VARCHAR2
)
IS
BEGIN
EXECUTE IMMEDIATE 'BEGIN theString := ''test''; END; ';
END;
它将无法正常工作,因为theString
的范围不会转移到动态PL / SQL块。换句话说,动态PL / SQL块不会“继承”任何变量,无论它在何处执行。
[2] 你可能会说“好,没有恐慌,我可以给动态PL / SQL块提供输入/输出参数,对吧?”。当然可以,但你猜怎么着:你只能给出/出来的SQL类型!另一方面,真正的PL / SQL类型(例如myTable%rowtype
)不被接受为动态PL / SQL块的输入。所以 hmmftg 的答案也不会起作用:
-- I've reduced the code to the interesting part
dynamic_request := 'BEGIN :t_row.' || col_name || ':= 0.001; END;';
EXECUTE IMMEDIATE dynamic_request USING IN OUT tRow;
-- (where tRow is of type myTable%ROWTYPE)
由于tRow
是MyTable%ROWTYPE,因此它不是有效的SQL类型,因此无法作为动态PL / SQL块的输入。
解决方案谁会想到全局变量会来拯救这一天?正如我们在 [1] 中所说,我们没有引用动态PL / SQL块之外的任何变量。但我们仍然可以访问包头中定义的全局变量!
我们假设我有一个包kingPackage
,我在其中定义了以下内容:
tempVariable myTable%ROWTYPE;
然后我可以这样做:
-- Copy tRow into temp variable
kingPackage.tempVariable := tRow;
-- We modify the column of the temp variable
vString := 'BEGIN kingPackage.tempVariable.' || col_val || ' := ' || TO_CHAR(vNumber) ||'; END;';
EXECUTE IMMEDIATE vString;
-- The column value has been updated \o/
tRow := kingPackage.tempVariable;
你去,伙计们! 祝你有愉快的一天
答案 1 :(得分:1)
试试这个:
CREATE OR REPLACE PROCEDURE ROW_CHANGER(
tRow IN MyTable%ROWTYPE,
col_name IN VARCHAR,
nValue IN NUMBER)
AS
dynamic_request VARCHAR(300);
BEGIN
dynamic_request := 'BEGIN :t_row.'||COL_NAME ||':= :n_value; END;';
EXECUTE IMMEDIATE dynamic_request
USING IN OUT TROW, IN nValue;
END;
这是因为在EXECUTE IMMEDIATE
tRow MyTable%ROWTYPE
未定义,
所以我们用using
语句定义它。