Sql 根据参数返回不同表的存储过程
我想写一个以@FirmId为参数的存储过程,我将根据这个参数使用相关的表 我想要得到的(但我不想使用)是这样的:Sql 根据参数返回不同表的存储过程,sql,sql-server,tsql,parameters,Sql,Sql Server,Tsql,Parameters,我想写一个以@FirmId为参数的存储过程,我将根据这个参数使用相关的表 我想要得到的(但我不想使用)是这样的: CREATE PROCEDURE spFirmDetailGetByFirmId @FirmId AS INT AS BEGIN IF @FirmId = 1 SELECT * FROM Firm1 ELSE IF @FirmId = 2 SELECT * FROM Firm2 . .
CREATE PROCEDURE spFirmDetailGetByFirmId
@FirmId AS INT
AS
BEGIN
IF @FirmId = 1
SELECT * FROM Firm1
ELSE IF @FirmId = 2
SELECT * FROM Firm2
.
.
.
.
ELSE IF @FirmId = 1000
SELECT * FROM Firm1000
END
我也不想创建查询字符串,然后执行它,就像在空闲代码块中那样。因为实际查询太复杂,如果使用此选项,将很难管理
CREATE PROCEDURE spFirmDetailGetByFirmId
@FirmId AS INT
AS
BEGIN
DECLARE @Query AS NVARCHAR(MAX) = 'SELECT * FROM Firm'
SET @Query = @Query + CAST(@FirmId AS NVARCHAR(10))
EXEC(@Query)
END
还有其他选择吗?
谢谢。我接受您的回答。表是相同的,将保持不变,以建议两种方法:
DECLARE @Firm VARCHAR(10)='Firm3';
SELECT * FROM Firm1 WHERE @Firm='Firm1'
UNION ALL
SELECT * FROM Firm2 WHERE @Firm='Firm2'
UNION ALL
SELECT * FROM Firm3 WHERE @Firm='Firm3'
[...]
UNION ALL
SELECT * FROM Firm1000 WHERE @Firm='Firm1000'
二是:
DECLARE @query NVARCHAR(MAX)='SELECT * FROM ####';
SET @query=REPLACE(@query,'####',@Firm);
EXEC (@query)
第二个可以与
视图
(代替@query
)一起使用,您可以将视图的定义读入变量并动态创建ALTER VIEW
-语句。。。您的过程将调用相同的视图(但并行调用会导致崩溃!)此代码可以在存储过程中使用,以便在每次需要添加列时自动创建视图
declare @tableId int
declare @columns varchar(max)
declare @tablesCount int
declare @tableName varchar(255)
declare @query varchar(255)
declare @id int
declare @result nvarchar(max)
set @columns = ''
set @tableName = 'Firm'
set @id = 1
set @result = ''
--Base table
select @tableId = object_id from sys.tables where name =@tableName
--Count how many table with the 'same name'
select @tablesCount= count(*) from sys.tables where name like @tableName+'%'
--Build Columns to add in the view
select @columns =@columns+name+', 'from Sys.columns where object_id = @tableId
--Drop View
set @result = 'Drop view vw_'+@tableName
exec sp_executesql @result
set @result=''
while(@id<=@tablesCount)
Begin
declare @idVarchar varchar(10)
set @idVarchar = cast(@id as varchar(10))
set @result =@result+'Select '+@columns+@idVarchar+' as FirmId from '+@tableName+@idVarchar
+'
Union all
'
set @id =@id+1
End
set @result = substring(@result, 1, len(@result)-12)
set @result='Create view vw_'+@tableName+' as
'+@result
exec sp_executesql @result
declare@tableId int
声明@columns varchar(最大值)
声明@tableCount int
声明@tableName varchar(255)
声明@query varchar(255)
声明@id int
声明@result nvarchar(最大值)
设置@columns=''
set@tableName='Firm'
设置@id=1
设置@result=''
--基表
从sys.tables中选择@tableId=object\u id,其中name=@tableName
--计算有多少表具有“相同名称”
从sys.tables中选择@tableCount=count(*),其中的名称类似于@tableName+“%”
--生成要添加到视图中的列
从Sys.columns中选择@columns=@columns+name+,'其中object_id=@tableId
--俯视图
set@result='下拉视图vw_uz'+@tableName
exec sp_executesql@result
设置@result=''
虽然(@idI不相信还有其他选项,但如果表是相同的,但数字是相同的,那么“解决方案”可能是将所有数据放在一个表中,并将数字作为标识符。如果不能做到这一点,动态SQL似乎是您的最佳选项,尽管重写可能会很烦人。唯一的其他选项(也是最好的选项)就是重新设计您的表,以便只有一个FirmId
列的firm
表。@Blorgbeard我知道设计不好,但不幸的是数据库不在我的控制之下。它是由另一家公司设计的,我只需在我的报告屏幕上使用它。如果所有表都有相同的列,则创建一个视图并添加数据FirmIdBtw的计算列:为什么投票反对?OP清楚地表明,常用的方法是明确的(带有代码示例!)并要求提供替代方案。这有什么不对?投票获得补偿…感谢您的分享。这是一种使用sys.tables的有趣方式。我将尝试针对我的实际案例优化您的查询。这种过程的想法将用于管理员,例如,我有一个创建文件组的过程,cr在其上创建一些表并归档旧数据,然后将这些文件标记为只读,并重建历史报告中使用的视图