如何执行带参数的存储过程?
How to execute a stored procedure with parameters?
我有一个包含 40 table 的数据库。我想通过使用单个存储过程 select 来自某个 table 的数据。首先table(TblSPAU1)
有6列,命名为:ID, COL_SPAU1_EA, COL_SPAU1_EQ, COL_SPAU1_ore, COL_SPAU1_nivel, DateTime
。例如第四个 table (TblSPAU4)
,有这 6 列:ID, COL_SPAU4_EA, COL_SPAU4_EQ, COL_SPAU4_ore, COL_SPAU4_nivel, DateTime
。所以我想要的是 select 从 table X 从 DateStart
到 DateStop
的数据。到目前为止我所做的是:
USE [DBRapBreaza]
GO
/****** Object: StoredProcedure [dbo].[PS_SpauOPompa] Script Date: 12/19/2018 15:48:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PS_SpauOPompa]
@DataStart datetime,
@DataStop datetime,
@val int
AS
BEGIN
SET NOCOUNT ON;
declare @sql NVARCHAR(max)
declare @col1 varchar
set @col1='ID'
declare @col2 varchar(25)
set @col2='COL_SPAU'+CONVERT(VARCHAR, @val)+'_EA'
declare @col3 varchar
set @col3='DateTime'
set @sql='select [ID]'+@col2+' FROM [DBRapBreaza].[dbo].[TblSPAU'+CONVERT(VARCHAR, @val)+ '] WHERE DateTime between'+CONVERT(VARCHAR(25), @DataStart,121)+ 'and'+CONVERT(VARCHAR(25), @DataStop,121)+';'
END
EXEC sp_sqlexec @sql, N'@DataStart datetime,@DataStop datetime,@val int', @DataStart, @DataStop, @val
我想select,比方说,来自某个table的ID和拳头列。 @val 表示我想要 select 数据的 table 个数。
在 sp_sqlexec
上,我有一个工具提示,提示我指定的参数太多。当我执行 EXEC 时,它抛出这个错误:Msg 137, Level 15, State 2, Line 1. Must declare the scalar variable "@sql".
我的问题是我应该如何执行这个存储过程?
非常感谢!
首先,您的字符串构建中需要一些空格。具体修改为:
set @sql= 'select [ID], '+@col2+' FROM [DBRapBreaza].[dbo].[TblSPAU'+CONVERT(VARCHAR, @val)+ '] WHERE DateTime between '''+CONVERT(VARCHAR(25), @DataStart,121)+ ''' and '''+CONVERT(VARCHAR(25), @DataStop,121)+''';'
这将使您的 SQL 看起来像这样:
select [ID], COL_SPAU1_EA FROM [DBRapBreaza].[dbo].[TblSPAU1] WHERE DateTime between '2018-12-20 14:18:02.170' and '2018-12-20 14:18:02.170';
相对于以下内容:
select [ID]COL_SPAU1_EA FROM [DBRapBreaza].[dbo].[TblSPAU1] WHERE DateTime between2018-12-20 14:19:13.167and2018-12-20 14:19:13.167;
缺少:
- 第一列后的逗号
- Space 逗号名称之间(语义)
- Space字后between
- 引用将根据您的参数进行评估的日期
- Space 在
between
语句 between
的 where
子句中的 和 之前和之后
这就是为什么在测试动态 SQL 时使用 PRINT @sql
总是明智的原因。
然后,将 END
移动到脚本的最底部后,将执行更改为:
EXEC sp_executesql
@sql,
N'@DataStart datetime, @DataStop datetime, @val int',
@DataStart, @DataStop, @val
这将为您留下以下代码:
USE [DBRapBreaza]
GO
/****** Object: StoredProcedure [dbo].[PS_SpauOPompa] Script Date: 12/19/2018 15:48:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PS_SpauOPompa]
@DataStart datetime,
@DataStop datetime,
@val int
AS
BEGIN
SET NOCOUNT ON;
declare @sql NVARCHAR(max)
declare @col1 varchar --missing a length here
declare @col2 varchar(25)
declare @col3 varchar --missing a length here
set @col1='ID'
set @col2='COL_SPAU'+CONVERT(VARCHAR, @val)+'_EA'
set @col3='DateTime'
set @sql= 'select [ID], '+@col2+' FROM [DBRapBreaza].[dbo].[TblSPAU'+CONVERT(VARCHAR, @val)+ '] WHERE DateTime between '''+CONVERT(VARCHAR(25), @DataStart,121)+ ''' and '''+CONVERT(VARCHAR(25), @DataStop,121)+''';'
--print @sql;
EXEC sp_executesql
@sql,
N'@DataStart datetime, @DataStop datetime, @val int',
@DataStart, @DataStop, @val;
END
请注意,您没有为 @col1
或 @col3
指定长度,它们默认为 8
,因此请小心。您从未使用过此变量,所以我不确定它的用途是什么。
我有一个包含 40 table 的数据库。我想通过使用单个存储过程 select 来自某个 table 的数据。首先table(TblSPAU1)
有6列,命名为:ID, COL_SPAU1_EA, COL_SPAU1_EQ, COL_SPAU1_ore, COL_SPAU1_nivel, DateTime
。例如第四个 table (TblSPAU4)
,有这 6 列:ID, COL_SPAU4_EA, COL_SPAU4_EQ, COL_SPAU4_ore, COL_SPAU4_nivel, DateTime
。所以我想要的是 select 从 table X 从 DateStart
到 DateStop
的数据。到目前为止我所做的是:
USE [DBRapBreaza]
GO
/****** Object: StoredProcedure [dbo].[PS_SpauOPompa] Script Date: 12/19/2018 15:48:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PS_SpauOPompa]
@DataStart datetime,
@DataStop datetime,
@val int
AS
BEGIN
SET NOCOUNT ON;
declare @sql NVARCHAR(max)
declare @col1 varchar
set @col1='ID'
declare @col2 varchar(25)
set @col2='COL_SPAU'+CONVERT(VARCHAR, @val)+'_EA'
declare @col3 varchar
set @col3='DateTime'
set @sql='select [ID]'+@col2+' FROM [DBRapBreaza].[dbo].[TblSPAU'+CONVERT(VARCHAR, @val)+ '] WHERE DateTime between'+CONVERT(VARCHAR(25), @DataStart,121)+ 'and'+CONVERT(VARCHAR(25), @DataStop,121)+';'
END
EXEC sp_sqlexec @sql, N'@DataStart datetime,@DataStop datetime,@val int', @DataStart, @DataStop, @val
我想select,比方说,来自某个table的ID和拳头列。 @val 表示我想要 select 数据的 table 个数。
在 sp_sqlexec
上,我有一个工具提示,提示我指定的参数太多。当我执行 EXEC 时,它抛出这个错误:Msg 137, Level 15, State 2, Line 1. Must declare the scalar variable "@sql".
我的问题是我应该如何执行这个存储过程?
非常感谢!
首先,您的字符串构建中需要一些空格。具体修改为:
set @sql= 'select [ID], '+@col2+' FROM [DBRapBreaza].[dbo].[TblSPAU'+CONVERT(VARCHAR, @val)+ '] WHERE DateTime between '''+CONVERT(VARCHAR(25), @DataStart,121)+ ''' and '''+CONVERT(VARCHAR(25), @DataStop,121)+''';'
这将使您的 SQL 看起来像这样:
select [ID], COL_SPAU1_EA FROM [DBRapBreaza].[dbo].[TblSPAU1] WHERE DateTime between '2018-12-20 14:18:02.170' and '2018-12-20 14:18:02.170';
相对于以下内容:
select [ID]COL_SPAU1_EA FROM [DBRapBreaza].[dbo].[TblSPAU1] WHERE DateTime between2018-12-20 14:19:13.167and2018-12-20 14:19:13.167;
缺少:
- 第一列后的逗号
- Space 逗号名称之间(语义)
- Space字后between
- 引用将根据您的参数进行评估的日期
- Space 在
between
语句between
的where
子句中的 和 之前和之后
这就是为什么在测试动态 SQL 时使用 PRINT @sql
总是明智的原因。
然后,将 END
移动到脚本的最底部后,将执行更改为:
EXEC sp_executesql
@sql,
N'@DataStart datetime, @DataStop datetime, @val int',
@DataStart, @DataStop, @val
这将为您留下以下代码:
USE [DBRapBreaza]
GO
/****** Object: StoredProcedure [dbo].[PS_SpauOPompa] Script Date: 12/19/2018 15:48:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PS_SpauOPompa]
@DataStart datetime,
@DataStop datetime,
@val int
AS
BEGIN
SET NOCOUNT ON;
declare @sql NVARCHAR(max)
declare @col1 varchar --missing a length here
declare @col2 varchar(25)
declare @col3 varchar --missing a length here
set @col1='ID'
set @col2='COL_SPAU'+CONVERT(VARCHAR, @val)+'_EA'
set @col3='DateTime'
set @sql= 'select [ID], '+@col2+' FROM [DBRapBreaza].[dbo].[TblSPAU'+CONVERT(VARCHAR, @val)+ '] WHERE DateTime between '''+CONVERT(VARCHAR(25), @DataStart,121)+ ''' and '''+CONVERT(VARCHAR(25), @DataStop,121)+''';'
--print @sql;
EXEC sp_executesql
@sql,
N'@DataStart datetime, @DataStop datetime, @val int',
@DataStart, @DataStop, @val;
END
请注意,您没有为 @col1
或 @col3
指定长度,它们默认为 8
,因此请小心。您从未使用过此变量,所以我不确定它的用途是什么。