Sql 如何编写只截断特定模式的表的存储过程

Sql 如何编写只截断特定模式的表的存储过程,sql,sql-server,tsql,Sql,Sql Server,Tsql,我的数据库中有不同类型的模式。如果要删除具有暂存架构的表,如何修改此存储过程 CREATE PROC sp_Truncate AS BEGIN EXEC sp_MSforeachtable @command1 = 'TRUNCATE TABLE ?' END GO 是否有任何方法可以为架构名称传递参数(键入varchar或nvarchar)使用不带where子句的Delete语句是安全的,而不是truncate,如果有引用约束,则可能会失败。请尝试此查询 Declare @sql Nv

我的数据库中有不同类型的模式。如果要删除具有暂存架构的表,如何修改此存储过程

CREATE PROC sp_Truncate
AS
BEGIN
    EXEC sp_MSforeachtable @command1 = 'TRUNCATE TABLE ?'
END
GO

是否有任何方法可以为架构名称传递参数(键入
varchar
nvarchar

使用不带
where
子句的
Delete
语句是安全的,而不是
truncate
,如果有
引用约束,则可能会失败。请尝试此查询

Declare @sql Nvarchar(max)=''

SELECT @sql += ' delete from ' + s.NAME + '.' + t.NAME 
              +' Go DBCC CHECKIDENT ('''+s.NAME + '''.''' + t.NAME+''', RESEED, 0) GO '
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U' 
and s.name = 'schema_name' -- your schema name

Exec sp_executesql @sql
光标版本:

DECLARE @s_name VARCHAR(128)
DECLARE @t_name VARCHAR(128) 

DECLARE db_cursor CURSOR FOR  
SELECT  s.NAME as  Schema_Nam , t.NAME as Table_Name
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U' 
and s.name = 'schema_name'   

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @s_name,@t_name   

WHILE @@FETCH_STATUS = 0   
BEGIN   
       set @sql += ' delete from ' + s.NAME + '.' + t.NAME 
                  +' Go DBCC CHECKIDENT ('''+s.NAME + '''.''' + t.NAME+''', RESEED, 0) GO '   
FETCH NEXT FROM db_cursor INTO @s_name,@t_name   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

Exec sp_executesql @sql

可以安全地使用不带
where
子句的
Delete
语句,而不是
truncate
,如果有
引用约束,则该语句可能会失败。请尝试此查询

Declare @sql Nvarchar(max)=''

SELECT @sql += ' delete from ' + s.NAME + '.' + t.NAME 
              +' Go DBCC CHECKIDENT ('''+s.NAME + '''.''' + t.NAME+''', RESEED, 0) GO '
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U' 
and s.name = 'schema_name' -- your schema name

Exec sp_executesql @sql
光标版本:

DECLARE @s_name VARCHAR(128)
DECLARE @t_name VARCHAR(128) 

DECLARE db_cursor CURSOR FOR  
SELECT  s.NAME as  Schema_Nam , t.NAME as Table_Name
FROM   sys.tables t
       JOIN sys.schemas s
         ON t.[schema_id] = s.[schema_id]
WHERE  t.type = 'U' 
and s.name = 'schema_name'   

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @s_name,@t_name   

WHILE @@FETCH_STATUS = 0   
BEGIN   
       set @sql += ' delete from ' + s.NAME + '.' + t.NAME 
                  +' Go DBCC CHECKIDENT ('''+s.NAME + '''.''' + t.NAME+''', RESEED, 0) GO '   
FETCH NEXT FROM db_cursor INTO @s_name,@t_name   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

Exec sp_executesql @sql
您可以使用(请记住,
sp\msforeachtable
是未记录的存储过程):

sp\msforeachtable
参数:

@command1-是由执行的第一个命令 “sp_MSforeachtable”,定义为nvarchar(2000年)

@wherend-此参数可用于添加其他约束 帮助标识sysobjects表中将要删除的行 选中时,此参数也是nvarchar(2000)

警告:

我假设您的暂存区域表没有外键。否则它可能会失败

不要使用前缀
sp_u
命名存储过程: 在SQL Server中,sp_uu前缀指定系统存储过程。如果 您可以在存储过程中使用该前缀,即 过程可能与系统存储过程的名称冲突 这将在未来创建。如果发生此类冲突,您的 如果应用程序引用该过程,则应用程序可能会中断 没有按架构限定引用。在这种情况下 名称将绑定到系统过程而不是您的过程

您可以使用(请记住,
sp\msforeachtable
是未记录的存储过程):

sp\msforeachtable
参数:

@command1-是由执行的第一个命令 “sp_MSforeachtable”,定义为nvarchar(2000年)

@wherend-此参数可用于添加其他约束 帮助标识sysobjects表中将要删除的行 选中时,此参数也是nvarchar(2000)

警告:

我假设您的暂存区域表没有外键。否则它可能会失败

不要使用前缀
sp_u
命名存储过程: 在SQL Server中,sp_uu前缀指定系统存储过程。如果 您可以在存储过程中使用该前缀,即 过程可能与系统存储过程的名称冲突 这将在未来创建。如果发生此类冲突,您的 如果应用程序引用该过程,则应用程序可能会中断 没有按架构限定引用。在这种情况下 名称将绑定到系统过程而不是您的过程


通常,您可以用模式名限定表名,因此,不要只给出简单的表名,而要包括模式名,例如“schema.table”
sp_MSforeachtable
sp_MSforeachdb
都因缺少表和数据库而臭名昭著。按照
MM93
答案中的建议使用
sys
目录视图。
DELETE
DROP
TRUNCATE
:您真正想要的是哪一个?旁注:您不应该在存储过程中使用
sp_
前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用
sp.
并使用其他东西作为前缀,或者根本不使用前缀!通常,您可以用模式名限定表名,因此,不要只给出简单的表名,而要包括模式名,例如“schema.table”
sp_MSforeachtable
sp_MSforeachdb
都因缺少表和数据库而臭名昭著。按照
MM93
答案中的建议使用
sys
目录视图。
DELETE
DROP
TRUNCATE
:您真正想要的是哪一个?旁注:您不应该在存储过程中使用
sp_
前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用
sp.
并使用其他东西作为前缀,或者根本不使用前缀!仍然可能是错误的,请参见:代码类似于
从表中选择@Variable+=someField
依赖于物理实现和内部访问路径,我将坚持使用
截断
而不是删除,日志记录更少,速度更快,但您的sys cataloge view方法优于
sp_MSforeachtable
方法。此外,仅当该表未被任何其他表引用时,才能使用Truncate。@lad2025-是的,我知道。但对我来说,它从未失败过。我们可以使用游标instead@M.Ali-这就是我选择删除的原因。
@MM93太好了,还添加了截断重置标识列而不删除的选项。我没有更多的问题,仍然可能是错误的,请看:代码类似于
SELECT@Variable+=someField
依赖于物理实现和内部访问路径,我将坚持使用
截断
而不是删除,日志记录更少,速度更快,但您的sys cataloge view方法优于
sp_MSforeachtable
方法。此外,仅当该表未被任何其他表引用时,才能使用Truncate。@lad2025-是的,我知道。但对我来说,它从未失败过。我们可以使用游标instead@M.Ali-这就是我选择删除的原因。
@MM93太好了,还添加了截断重置标识列而不删除的选项。我没有更多的问题了