witters
witters

Reputation: 741

How do I use parameters for the source in a MERGE statement in Informix?

I am trying to execute a merge statement against an Informix database as follows:

MERGE INTO aa_rec AS dest
USING (SELECT '123456' AS id, '111-222-3333' as phone, '' as phone_ext, 'CELL' as aa FROM sysmaster:'informix'.sysdual) AS src
ON dest.id = src.id AND dest.aa = src.aa
WHEN NOT MATCHED THEN 
    INSERT (dest.id, dest.aa, dest.beg_date, dest.phone, dest.phone_ext, dest.ofc_add_by)
    VALUES (src.id, src.aa, TODAY, src.phone, src.phone_ext, 'TEST')
WHEN MATCHED THEN UPDATE SET 
        dest.phone = src.phone, 
        dest.phone_ext = src.phone_ext, 
        dest.beg_date = '10/29/2019', 
        dest.ofc_add_by = 'TEST'

This statement works as is, with hard-coded values, but I would like to pass parameters for the values in the source table:

USING (SELECT ? AS id, ? as phone, ? as phone_ext, 'CELL' as aa FROM sysmaster:'informix'.sysdual) AS src

When I execute the statement with parameters and valid values, I receive this error:

E42000: (-201) A syntax error has occurred.

Are parameters supported in the source part of the MERGE statement? If they are, where is the error in my syntax?

For context, I'm calling this from ASP.NET using the OleDb provider for Informix.

Upvotes: 1

Views: 601

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754520

You have:

SELECT ? AS id, ? as phone, ? as phone_ext, 'CELL' as aa FROM sysmaster:'informix'.sysdual

You can't use placeholders (? symbols) for 'structural' elements of a SELECT statement. You can't provide column names in the placeholders. And passing numbers etc as values via placeholders in the select-list doesn't work either.

I'd probably create a temp table of the appropriate shape, and insert a row into that, and then use the temp table in the select statement:

SELECT '123456' AS id, '111-222-3333' AS phone, '' AS phone_ext, 'CELL' AS aa
  FROM sysmaster:'informix'.sysdual
  INTO TEMP phone_data;

MERGE INTO aa_rec AS dest
USING (SELECT * FROM phone_data) AS src
   ON dest.id = src.id AND dest.aa = src.aa
 WHEN NOT MATCHED THEN 
      INSERT (dest.id, dest.aa, dest.beg_date, dest.phone, dest.phone_ext, dest.ofc_add_by)
          VALUES (src.id, src.aa, TODAY, src.phone, src.phone_ext, 'TEST')
 WHEN MATCHED THEN UPDATE SET 
          dest.phone = src.phone, 
          dest.phone_ext = src.phone_ext, 
          dest.beg_date = '10/29/2019', 
          dest.ofc_add_by = 'TEST'
;

DROP TABLE phone_data;

It might be better/safer to create the temp table explicitly rather than to use the INTO TEMP clause. The types are not necessarily what you'd expect (CHAR(6), CHAR(12), VARCHAR(1), CHAR(4)) — though that may not matter.

Clearly, once the temp table exists, you can insert whatever data is appropriate into the temp table using any mechanism that's available:

INSERT INTO phone_data(id, phone, phone_ext, aa) VALUES(?, ?, ?, ?)

Remember that temp tables are private to a session — you can have lots of people all using the same temporary table name at the same time without interfering with each other.

Upvotes: 1

Related Questions