1

I'm trying to move a column from one table to another (here's the post for that),

However this runs as a task, and may run after it has already completed so I need a clause that prevents the logic from running again. I thought I could achieve this with an IF:

IF EXISTS ( 
    SELECT * 
    FROM sys.columns 
    WHERE object_id = OBJECT_ID(N'Table_A')
        AND name = 'internalID'
)
BEGIN
    UPDATE Table_B
        SET b.internalID = a.internal_ID
    FROM Table_B b INNER JOIN
            Table_A a
            ON a.id = b.FK_toTableA;

    ALTER TABLE Table_A DROP COLUMN internalID;
END

However, I get an error at

SET b.internalID = a.internal_ID

The error is:

Invalid column name 'internalID'.

But Only If a.internalID doesn't exist anymore.

Travis Heeter
  • 13,002
  • 13
  • 87
  • 129
  • 3
    It should be `WHERE object_id = OBJECT_ID(Table_A) AND name = 'internalID'` <- quotes missing – juergen d Aug 20 '18 at 14:29
  • 3
    Yes, you're getting a *compilation* error. You cannot fix compilation errors with *runtime* logic. You need to force the later code to not be compiled until you know it's valid, by e.g. using dynamic SQL. – Damien_The_Unbeliever Aug 20 '18 at 14:31

1 Answers1

1

I had to use EXEC sp_executesql:

IF EXISTS ( 
    SELECT * 
    FROM sys.columns 
    WHERE object_id = OBJECT_ID(N'Table_A')
        AND name = 'internalID'
)
BEGIN
    EXEC sp_executesql N'UPDATE Table_B
            SET b.internalID = a.internal_ID
        FROM Table_B b INNER JOIN
                Table_A a
                ON a.id = b.FK_toTableA';

    ALTER TABLE Table_A DROP COLUMN internalID;
END

I guess because SQL Server complies the whole thing - even that stuff bypassed via conditional logic - before running the script.

Here's a good article about what sql_executesql does, compared to EXEC, but it basically boils down to more injection prevention.

Travis Heeter
  • 13,002
  • 13
  • 87
  • 129
  • 1
    `sql_execsql` doesn't exist on any version, so far as I'm aware, so if that's what you put in, it was right to complain. `sp_executesql` on the other hand is well documented and exists on all versions of SQL Server you're likely to run into these days. – Damien_The_Unbeliever Aug 21 '18 at 13:49