views:

48

answers:

3

In my stored procedure I have to pass a table and column name which may change everytime. So I build command and execute it. I want the output in another variable @curr_id. This store procedure will be called by second stored procedure by using @curr_id as input.

My problem is populating the @curr_id vriable. It is returned as zero. If I remove the curr_id variable then it works(see commented line)

Can someone pl. tell me - how to get @curr_id populated and returned as OUTPUT? - how to call the first stored proc from a second stored proc?

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
A: 
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
Beth
I just want to get the output in curr_id and call the stored proc from another stored proc. This looks complicated to me.
you get the output in the ret variable and you can ignore all the code about the params. If you want, you can also ignore the try/catch block.
Beth
+2  A: 

Because EXEC runs in a different context, it is not aware of your @curr_id variable. Instead, you can place the output of your dynamic SQL into a table variable, and then use that to set @curr_id.

Also, 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

Then, an example of calling this procedure from within another could be something like this. The important key is to use the OUTPUT keyword here in the call as well as in the declaration of the procedure above.

    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
Joe Stefanelli
A: 

You can use the OUTPUT parameter in 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('+@ColName+') FROM '+@TblName 

EXEC sp_executesql 
  @cmd, 
  N'@curr_id_out nvarchar(max) OUTPUT', 
  @curr_id_out = @curr_id OUTPUT

END 

I would be remiss not to mention that, in this case, using EXEC(@cmd) or sp_executesql(@cmd) leaves you vulnerable to SQL injection attacks.

I recommend adding something like the following to the beginning of the stored procedure:

SELECT 
  @ColName = REPLACE(
             REPLACE(
             REPLACE(@ColName, ';', ''), '-', ''), '''', ''),
  @TblName = REPLACE(
             REPLACE(
             REPLACE(@TblName, ';', ''), '-', ''), '''', '')
8kb