我尝试构建动态SQL,将值选择到变量中并在where子句中使用变量。我的语法不正确,但我不熟悉Oracle语法的细微之处。
SET SERVEROUTPUT ON
DECLARE
v_strWorkstationOld varchar(40) := 'hostname1';
v_strWorkstationNew varchar(40) := 'hostname2';
v_intnumOld int := 0;
v_intnumNew int := 0;
v_sql varchar(800);
BEGIN
IF ((v_strWorkstationOld = '') OR (v_strWorkstationNew = '')) THEN
dbms_output.put_line('Workstation must have a value. Please update the value in the script and run it again.');
ELSE
v_sql := 'SELECT num INTO v_intnumOld FROM hsi.hostnametable WHERE name = ''' || v_strWorkstationOld || '''';
--dbms_output.put_line (v_sql);
EXECUTE IMMEDIATE (v_sql);
IF ((v_intnumOld > 0) AND (v_intnumNew > 0)) THEN
dbms_output.put_line('Found for Workstation: ' || v_strWorkstationNew);
ELSE
dbms_output.put_line('No registernum found for Workstation: ' || v_strWorkstationNew);
END IF;
END IF;
dbms_output.put_line('COMMIT;');
COMMIT;
END;
感谢。
答案 0 :(得分:0)
您不需要为此使用动态SQL,它是一个简单的select into
子句:
...
ELSE
SELECT num INTO v_intnumOld
FROM hsi.hostnametable
WHERE name = v_strWorkstationOld;
IF ((v_intnumOld > 0) AND (v_intnumNew > 0)) THEN
...
如果你有一个确实需要动态SQL的更复杂的场景,你可以使用绑定变量而不是连接变量值,然后语法如下:
v_sql := 'SELECT num FROM hsi.hostnametable WHERE name = :b0';
--dbms_output.put_line (v_sql);
EXECUTE IMMEDIATE v_sql INTO v_intnumOld USING v_strWorkstationOld;
- 如果动态SQL语句是一个最多可以返回一行的SELECT语句,则在INTO子句中放置绑定变量(定义),在USING子句中放入in-bind变量。
...和this example。
但是不要为您的示例代码执行此操作,请使用静态SQL。
这也不符合您的想法:
IF ((v_strWorkstationOld = '') OR (v_strWorkstationNew = '')) THEN
空字符串''
与Oracle中的null
相同,您不能使用相等运算符来检查null。您需要使用is null
代替:
IF (v_strWorkstationOld IS NULL OR v_strWorkstationNew IS NULL) THEN
虽然因为你在声明它们时给出了两个变量值,但无论如何都不能为null。您也没有做任何事情来将v_intnumNew
从其默认值零更改为更改v_strWorkstationNew
。并且您不需要在查询后提交。