Oracle - 在select into和where中使用变量的动态查询

时间:2014-12-29 17:32:19

标签: sql oracle variables

我尝试构建动态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;

感谢。

1 个答案:

答案 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;

来自the documentation

  
      
  • 如果动态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。并且您不需要在查询后提交。