The way that works best for me, to write stored procedures that execute dynamic SQL, is by not using "EXEC sp_executesql" when I start writing the stored procedure, but by using "PRINT" statements.
I make sure I get to see each and every SQL that the stored procedure generates. I copy them from the Messages tab and execute them from within Management Studio. Only after all SQLs work as intended, I allow my stored procedure to "EXEC sp_executesql" (instead of simply PRINTing the SQL statements).
Debugging works very fast this way. The most problems I encountered so far, are the result of missing spaces, like 'FROMMyTableName' or 'WHEREId = 12'.
You will have to test this as the certificate user or with an account that has similar rights. And if you can avoid using dynamic SQLs, avoid them.
if the statements are inside the stored procedure together, they will be processed simultaneously and because the tables are related that way it will cause a problem.
No, the statements in a stored procedure are processed sequentially, not in parallel. A stored procedure executes in a single thread, just as if you had issued the queries one after another... not simultaneously.
There are some optimizations you could make, however.
If the `titnum` table doesn't have a multi-column index on the three columns (titvalpag, titemi, titnum) together, you should probably add one.
The delete statements can be rewritten without the IN()
.
Use caution with this, because doing it incorrectly will remove the wrong data.
delete from mov_pedido
where pednot in(select distinct titnum
from mov_titulo
where titnum like 'A4%'
and titemi <='2012-01-01' and titvalpag >0);
...becomes...
DELETE p
FROM mov_pedido p
JOIN mov_titulo m ON m.titnum = p.pednot
WHERE m.titnum like 'A4%' and m.titemi <='2012-01-01' and m.titvalpag >0;
This is the multi-table delete syntax. "DELETE p" will only remove the rows from "p" (an alias for mov_pedido) that match rows in "m" (mov_titulo). It won't remove the rows from "m" unless you say "DELETE p, m" -- so don't do that.
The mov_pedido table (and the others) should have an index on the column you're using to join (pednot, etc.) if they don't already.
Best Answer
Use a cursor to loop through the table, then use
EXEC sys.sp_executesql
for each row.The following code relies on a temporary table, named
#t
, which contains various DML statements:The output looks like:
Compound statements, like
IF EXISTS (...)
must occur in a single statement. If you need to run all rows as if they were a single statement, simply concatenate the output from each row, then usesys.sp_executesql
on the result, as in:The output from the above code:
If you are allergic to cursors, you could use a set-based approach, such as:
Understand there is a slight chance that using the set-based approach with string concatenation may cause the commands to be executed in the wrong order, even though there is an
ORDER BY
clause. The SQL Server query optimizer can do strange things under the hood if it thinks the query will perform faster.