I'm trying to create a stored procedure to delete all data from dynamically selected tables.
I used this code, but it's not working. Any suggestion?
CREATE PROCEDURE spDynamicDeleteTable
@table NVARCHAR(100)
AS
BEGIN
DECLARE @Sql NVARCHAR(MAX)
SET @Sql= 'DELETE FROM'+ @table
EXECUTE sp_executesql @Sql
END
You are missing a space.
Set @Sql= 'Delete from'+ @table
would become
Delete fromelbat
if @table = 'elbat'
. That isn't valid syntax.
Add a space after "from". It's also advisable to use quotename()
to prevent funny things from happen with unusual table names.
Set @Sql= 'Delete from ' + quotename(@table)
Some further notes:
@table
should better be declared as a sysname
rather than nvarchar(100)
. sysname
is a type extra for object names.
Be aware, that you have to take great care regarding the rights this stored procedure is executed with in order to prevent it from being abused to delete arbitrary data.
This will protect against sql injections and also allow you to supply the schema as an optional parameter
ALTER PROCEDURE spDynamicDeleteTable
@table nvarchar(128),
@schema nvarchar(128) = 'dbo'
AS
BEGIN
DECLARE @Sql NVARCHAR(MAX)
SELECT
@Sql= 'DELETE FROM '+ quotename(s.SCHEMA_NAME) + '.'+ quotename(t.NAME)
FROM sys.tables t
CROSS JOIN
[INFORMATION_SCHEMA].[SCHEMATA] s
WHERE
t.NAME = @table
and s.SCHEMA_NAME = @schema
IF @@rowcount = 1
EXECUTE sp_executesql @Sql
ELSE
print 'failed'
END
Firstly, with regards to dynamic SQL you are opening yourself up to SQL Injection , and the issue you are seeing is due to the lack of the space as mentioned in the other answer and comments.
But....
While you could do something like this, you are potentially going to encounter issues when you try to run it, mainly related to referential integrity.
Take this example:
User Table
UserId | Name
1 | Bob
2 | Jim
UserOrders Table
OrderId | UserId
1 | 1
2 | 1
3 | 2
4 | 2
Say you are going to delete all records in the User
table. The User
table may have related information in UserOrders
, so because the second table links to the primary key on the first table, you won't be able to delete records in the first table unless all related data is deleted, and the only way to do that is with cascade deletes, which is where this type of solution will become dangerous.
If you're only concerned about static, un-linked data, then it could work, but if there are relationships between the tables then I would advise against this type of solution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.