在我的 Node 应用程序中查询 table 名称时出现 "SQL command not properly ended" 错误消息

"SQL command not properly ended" error message when querying for table names in my Node application

使用 node-oracledb 执行以下查询时出现以下错误:

SELECT OBJECT_NAME
FROM ALL_OBJECTS || '@' || :db
WHERE OWNER = :schema
    AND (
        OBJECT_TYPE = ''TABLE''
        OR OBJECT_TYPE = ''VIEW''
        OR OBJECT_TYPE = ''SYNONYM''
    )
ORDER BY OBJECT_NAME

如果我在 Oracle 控制台中执行此查询(当然,用占位符代替实际值),它执行得很好。但是,当我在我的 Node 应用程序中执行此操作时,出现以下错误:

"ORA-00933: SQL command not properly ended"

是否有人能够帮助我解决此错误的原因?我可以确认我的占位符确实填充了我希望它们填充的值。

谢谢!

编辑:

即使我尝试这样做:

SELECT OBJECT_NAME
FROM ALL_OBJECTS || @ || :db

我仍然遇到同样的错误。

SELECT OBJECT_NAME
FROM ALL_OBJECTS || '@' || :db
WHERE OWNER = :schema
    AND (
        OBJECT_TYPE = 'TABLE'
        OR OBJECT TYPE = 'VIEW'
        OR OBJECT_TYPE = 'SYNONYM'
    )
ORDER BY OBJECT_NAME
  • 首先,您的查询有错别字。您在 OBJECT TYPE OR OBJECT TYPE = 'VIEW'.

  • 中缺少 下划线
  • 您不能使用动态对象名称执行SQL。 SQL 必须有静态对象名称。 DATABASE LINK是一个数据库对象,你必须在运行时提供静态名称。您只能提供 占位符 作为文字 的 绑定变量。

如果你想让它动态化,那么你需要(ab)在PL/SQL中使用EXECUTE IMMEDIATE。需要动态准备字符串,然后执行。

例如,在SQL*Plus:

var db varchar2(30);
var schema varchar2(30);
exec :db := 'database_name'
exec :schema := 'OWNER'

SET serveroutput ON
DECLARE
  v_sql         VARCHAR2(2000);
  v_object_name VARCHAR2(30);
BEGIN
  v_sql:= 'SELECT OBJECT_NAME
FROM ALL_OBJECTS@'||:db||' WHERE OWNER = :schema     
AND (        
OBJECT_TYPE = ''TABLE''
OR OBJECT_TYPE = ''VIEW''        
OR OBJECT_TYPE = ''SYNONYM''
)
ORDER BY OBJECT_NAME';
  dbms_output.put_line(v_sql);
  execute immediate v_sql into v_object_name using :db, :schema;
END;
/

或者,您可以将 DATABASE LINK 作为静态名称:

首先我创建数据库link:

SQL> CREATE DATABASE LINK TEST
  2    CONNECT TO SCOTT IDENTIFIED BY tiger USING 'pdborcl';

Database link created.

tnsnames.ora 文件中添加了以下条目:

test =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL=TCP)(HOST=ocalhost)(PORT=1521))
    (CONNECT_DATA = 
      (SERVER=DEDICATED)
      (SERVICE_NAME=pdborcl.in.oracle.com)
    )
  )

让我们在SQL*Plus:

中执行
SQL> var schema varchar2(30);
SQL> exec :schema := 'SCOTT'

PL/SQL procedure successfully completed.

SQL> SELECT OBJECT_NAME
  2  FROM ALL_OBJECTS@test
  3  WHERE OWNER = :schema
  4      AND (
  5          OBJECT_TYPE = 'TABLE'
  6          OR OBJECT_TYPE = 'VIEW'
  7          OR OBJECT_TYPE = 'SYNONYM'
  8      )
  9  ORDER BY OBJECT_NAME
 10  /

OBJECT_NAME
------------------------------------------------------------
BONUS
DEPT
EMP
EMP_VIEW
SALGRADE

设法解决了这个问题。结果证明这只是我对变量绑定工作原理的误解。我以为我可以在查询中绑定到我想要的任何内容。结果你不能:P

我将查询修改为如下所示:

SELECT OBJECT_NAME
FROM ALL_OBJECTS@<HARDCODED DB NAME HERE>
WHERE OWNER = :schema
AND (
    OBJECT_TYPE = 'TABLE'
    OR OBJECT_TYPE = 'VIEW'
    OR OBJECT_TYPE = 'SYNONYM'
)
ORDER BY OBJECT_NAME;

一切都很完美!