In a Snowflake stored procedure, I'm executing dynamic SQL. I want to pass the table names into the queries using bound variables. Because they are variables, I need to wrap them with IDENTIFIER() (https://docs.snowflake.com/en/sql-reference/identifier-literal.html).
However, this seems to work in some cases and not others.
This works (using Javascript string interpolation to put the target table into the query, but using bound variables for the TMP table) :
var deleteResults = snowflake.execute({sqlText:`
DELETE FROM ${threePartTargetTable} TARGET
USING IDENTIFIER(?) TMP
WHERE TARGET.DOCUMENT_DESCRIPTOR_ID = TMP.DOCUMENT_DESCRIPTOR_ID
AND TARGET.DOCUMENT_DESCRIPTOR_ID NOT IN (SELECT DOCUMENT_DESCRIPTOR_ID FROM IDENTIFIER(?) WHERE END_ON = '12/31/9999 12:00:00 AM');`
,binds:[
tempTableName,
tempTableName
]});
But this (using bound variables for all of the table names) returns
invalid identifier 'TARGET.DOCUMENT_DESCRIPTOR_ID'
var deleteResults = snowflake.execute({sqlText:`
DELETE FROM IDENTIFIER(?) TARGET
USING IDENTIFIER(?) TMP
WHERE TARGET.DOCUMENT_DESCRIPTOR_ID = TMP.DOCUMENT_DESCRIPTOR_ID
AND TARGET.DOCUMENT_DESCRIPTOR_ID NOT IN (SELECT DOCUMENT_DESCRIPTOR_ID FROM IDENTIFIER(?) WHERE END_ON = '12/31/9999 12:00:00 AM');`
,binds:[
threePartTargetTable,
tempTableName,
tempTableName
]});
This is another statement taken from the same procedure, which uses the same bound variable for the target table, and this works fine :
var insertResults = snowflake.execute({sqlText:`INSERT INTO IDENTIFIER(?)
(
DOCUMENT_DESCRIPTOR_ID
, NAME
)
SELECT TMP.DOCUMENT_DESCRIPTOR_ID
, TMP.NAME
FROM ${tempTableName} TMP
WHERE TMP.END_ON = '12/31/9999 12:00:00 AM'
AND TMP.DOCUMENT_DESCRIPTOR_ID NOT IN (SELECT DOCUMENT_DESCRIPTOR_ID FROM IDENTIFIER(?));`
,binds:[
threePartTargetTable,
threePartTargetTable
]});
The documentation doesn't mention any limitations of where IDENTIFIER() can be used. Does anyone know why the second piece of code doesn't work?