在我的 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;
一切都很完美!
使用 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;
一切都很完美!