我有这个存储过程,我想根据传递的变量动态选择表名,即@Practice_Short_Name
Create procedure [dbo].[GetCompleteCPTDetails]
@Practice_Short_Name varchar(50) is Null,
@Uploaded_Date varchar(30) is Null
as
begin
DECLARE @CPTtablename varchar(100)
DECLARE @vQuery NVARCHAR(100)
--Dynamically select Table name based on @practice_short_name
set @CPTtablename ='ACER_CLAIMS_MASTER_DETAIL_Hist_'+@Practice_Short_Name+''
SET @vQuery = 'select Practice_Short_Name,Service_Date_From,Carrier_Name,
Location_Description,Patient_Number,Patient_First_Name,
Patient_Last_Name,Voucher_Number,Procedure_Code,Service_Fees,
Service_Payments,Service_Adjustments,Acer_Status,Acer_Allowed_Amount
from '+@CPTtablename+'
where Uploaded_Date ='+@Uploaded_Date+' and
Practice_Short_Name ='+@Practice_Short_Name+'
order by acer_status asc, Service_Date_From desc, Patient_First_Name asc'
EXEC @vQuery
end
GO
但是在运行此proc时会抛出类似
的错误"找不到存储过程'选择Practice_Short_Name,Service_Date_From,Carrier_Name, Location_Description,Patient_Numb'"
任何人都可以解释我的错误。
答案 0 :(得分:2)
这样你就可以调用一个程序
EXEC @vQuery
但这样你运行动态sql
EXEC (@vQuery)
所以你的SP应该如下所示
Create procedure [dbo].[GetCompleteCPTDetails]
@Practice_Short_Name varchar(50) is Null,
@Uploaded_Date varchar(30) is Null
as
begin
DECLARE @CPTtablename varchar(100)
DECLARE @vQuery NVARCHAR(100)
--Dynamically select Table name based on @practice_short_name
set @CPTtablename ='ACER_CLAIMS_MASTER_DETAIL_Hist_'+@Practice_Short_Name+''
SET @vQuery = 'select Practice_Short_Name,Service_Date_From,Carrier_Name,
Location_Description,Patient_Number,Patient_First_Name,
Patient_Last_Name,Voucher_Number,Procedure_Code,Service_Fees,
Service_Payments,Service_Adjustments,Acer_Status,Acer_Allowed_Amount
from '+@CPTtablename+'
where Uploaded_Date ='+@Uploaded_Date+' and
Practice_Short_Name ='+@Practice_Short_Name+'
order by acer_status asc, Service_Date_From desc, Patient_First_Name asc'
EXEC (@vQuery)
end
GO
答案 1 :(得分:1)
用于存储查询的变量太短,无法存储整个查询文本
这意味着截断查询以修复@vQuery
变量的100个字符限制。
使用nvarchar(max)
代替nvarchar(100)
。
此外,使用动态SQL通常会带来安全隐患,为SQL Injection attacks留下空缺。您可能想要重新考虑您的设计并将所有数据保存在同一个表中,而不是在数据库中保留具有相同结构的不同表。
答案 2 :(得分:0)
需要纠正的两件事:动态查询变量的长度导致了这个问题。使用参数化动态查询来防止sql注入。
DECLARE @CPTtablename varchar(100)
DECLARE @vQuery NVARCHAR(2000) -- increased length, you can also use nvarchar(max)
--Dynamically select Table name based on @practice_short_name
SET @CPTtablename ='ACER_CLAIMS_MASTER_DETAIL_Hist_' + @Practice_Short_Name + ''
SET @vQuery = 'select Practice_Short_Name,Service_Date_From,Carrier_Name,
Location_Description,Patient_Number,Patient_First_Name,
Patient_Last_Name,Voucher_Number,Procedure_Code,Service_Fees,
Service_Payments,Service_Adjustments,Acer_Status,Acer_Allowed_Amount
from ' + @CPTtablename + '
where Uploaded_Date = @Uploaded_Date and
Practice_Short_Name = @Practice_Short_Name
order by acer_status asc, Service_Date_From desc, Patient_First_Name asc'
--dynamic query with input params
EXEC sp_executesql
@vQuery,
N'@Uploaded_Date varchar(30), @Practice_Short_Name varchar(50)',
@Uploaded_Date = @Uploaded_Date,
@Practice_Short_Name = @Practice_Short_Name