2010-08-17 89 views
1

在我的存储过程中,我必须传递一个可能每次都会更改的表和列名称。所以我建立命令并执行它。我想在另一个变量@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 '[email protected]_id+'= SELECT MAX('[email protected]+') FROM '[email protected]; 
--SET @cmd =N'SELECT MAX('[email protected]+') FROM '[email protected]; 

EXEC (@cmd) 

END 

回答

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 
+0

我只是想在curr_id输出,并从另一个存储过程调用存储过程。这对我来说看起来很复杂。 – vrao 2010-08-17 19:55:08

+0

你得到了ret变量的输出,你可以忽略所有关于参数的代码。如果你愿意,你也可以忽略try/catch块。 – Beth 2010-08-17 19:57:25

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 
0

可以使用OUTPUT参数sp_executesql

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('[email protected]+') FROM '[email protected] 

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, ';', ''), '-', ''), '''', '') 
相关问题