node.jsoracle-databaseplsqlnode-oracledbdatabase-link

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


I'm getting the following error when executing the following query with 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

If I execute this query in an Oracle console (substituting the placeholders for actual values, of course), it executes fine. However, when I execute this in my Node application, I get the following error:

"ORA-00933: SQL command not properly ended"

Is anyone able to assist with why I'm getting this error? I can confirm that my placeholders are definitely populating with the values I intended them to be populated with.

Thanks!

edit:

Even if I try do:

SELECT OBJECT_NAME
FROM ALL_OBJECTS || @ || :db

I still get the same error.


Solution

  • 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
    

    If you want to make it dynamic, then you need to (ab)use EXECUTE IMMEDIATE in PL/SQL. You need to prepare the string dynamically and then execute it.

    For example, In 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;
    /
    

    Or, you can have DATABASE LINK as a static name:

    First I create the database link:

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

    Added the following entry in tnsnames.ora file:

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

    Let's execute in 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