在我的存储过程中,我必须传递一个表和列名,它可能每次都会改变。所以我构建命令并执行它。我希望输出另一个变量@curr_id。第二个存储过程将使用@curr_id作为输入来调用此存储过程。
我的问题是填充@curr_id vriable。它返回零。如果我删除了 curr_id变量然后它工作(参见注释行)
有人可以。告诉我 - 如何填充@curr_id并作为OUTPUT返回? - 如何从第二个存储过程调用第一个存储过程?
ALTER PROCEDURE [dbo].[sp_astm_getcurrid]
@ColName as nvarchar(250),
@TblName as nvarchar(250),
@curr_id nvarchar(max) OUTPUT
AS
BEGIN
DECLARE @cmd nvarchar(max)
SET @cmd =N'SET '+@curr_id+'= SELECT MAX('+@ColName+') FROM '+@TblName;
--SET @cmd =N'SELECT MAX('+@ColName+') FROM '+@TblName;
EXEC (@cmd)
END
答案 0 :(得分:2)
因为EXEC在不同的上下文中运行,所以它不知道你的@curr_id变量。相反,您可以将动态SQL的输出放入表变量中,然后使用它来设置@curr_id。
另外,never start a stored procedure name with sp_。
ALTER PROCEDURE [dbo].[usp_astm_getcurrid]
@ColName as nvarchar(250),
@TblName as nvarchar(250),
@curr_id nvarchar(max) OUTPUT
AS
BEGIN
DECLARE @cmd nvarchar(max)
declare @dummy table (
ReturnColumn nvarchar(max)
)
SET @cmd = N'SELECT MAX(' + @ColName + N') FROM ' + @TblName;
insert into @dummy
(ReturnColumn)
exec (@cmd)
set @curr_id = (select ReturnColumn from @dummy)
END
然后,从另一个内部调用此过程的示例可能是这样的。重要的关键是在调用中以及上述过程的声明中使用OUTPUT关键字。
CREATE PROCEDURE CallMyProcedure
AS
BEGIN
declare @curr_id nvarchar(max)
exec dbo.usp_astm_getcurrid N'YourColumnName', N'YourTableName', @curr_id OUTPUT
select @curr_id
END
答案 1 :(得分:0)
Friend Function execSP(ByVal spName As String, Optional ByVal params As Collection = Nothing) As Integer
Dim cmd As SqlCommand
Dim param As SqlParameter
Dim ret As Integer
Dim iParam As Integer
cmd = New SqlCommand
cmd.CommandText = spName
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = _sqlConn
cmd.CommandTimeout = 0
If Not params Is Nothing Then
For iParam = 1 To params.Count
param = params(iParam)
cmd.Parameters.Add(param)
Next
End If
If _sqlConn.State <> ConnectionState.Open Then
_sqlConn.Open()
End If
Try
ret = cmd.ExecuteNonQuery()
Catch ex As Exception
Throw New Exception(ex.Message)
Finally
_sqlConn.Close()
End Try
Return ret
End Function
答案 2 :(得分:0)
您可以使用sp_executesql中的OUTPUT
参数:
ALTER PROCEDURE [dbo].[sp_astm_getcurrid]
@ColName as nvarchar(250),
@TblName as nvarchar(250),
@curr_id nvarchar(max) OUTPUT
AS
BEGIN
DECLARE
@cmd nvarchar(max)
SET @cmd =N'SELECT @curr_id_out = MAX('+@ColName+') FROM '+@TblName
EXEC sp_executesql
@cmd,
N'@curr_id_out nvarchar(max) OUTPUT',
@curr_id_out = @curr_id OUTPUT
END
我不能不提及,在这种情况下,使用EXEC(@cmd)或sp_executesql(@cmd)会使您容易受到SQL injection攻击。
我建议在存储过程的开头添加如下内容:
SELECT
@ColName = REPLACE(
REPLACE(
REPLACE(@ColName, ';', ''), '-', ''), '''', ''),
@TblName = REPLACE(
REPLACE(
REPLACE(@TblName, ';', ''), '-', ''), '''', '')