Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 根据参数返回不同表的存储过程_Sql_Sql Server_Tsql_Parameters - Fatal编程技术网

Sql 根据参数返回不同表的存储过程

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 . .

我想写一个以@FirmId为参数的存储过程,我将根据这个参数使用相关的表

我想要得到的(但我不想使用)是这样的:

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在其上创建一些表并归档旧数据,然后将这些文件标记为只读,并重建历史报告中使用的视图