none
sqlserver在存储过程中如何动态获取传入的参数值? RRS feed

  • 问题

  • 现在有个存储过程

    create proc up_test

    @a varchar(10)='3',

    @b varchar(10)='4

    as

    declare @s varchar(1000)

    select @s='@a=3,@b=4'

    print @s

    -----想把@a和@b的参数值赋值给@s,如何实现呢?存储过程的参数不是固定的,而且传的值也不是固定的

    比如 exec up_test '5','6' 则打印出来 @a='5',@b='6'

    如果 exec up_test 'm','n' 则打印出来 @a='m',@b='n'

    请大家看看有什么办法能实现到

    2013年6月17日 15:34

答案

  • 一般在调用程序上去处理, 出错记录会同时包含调用的语句和具体的参数值

    存储过程中, 估计你的想法是弄一个通用的 try ... catch 中的 catch 块错误处理吧,在这个处理中可以自动把当前存储过程的参数值给存储起来, 这个在sql server 中应该是没办法做的 

    • 已标记为答案 zyyjc 2013年9月23日 10:17
    2013年6月18日 6:31

全部回复

  • You can print @a and @b in sp directly like:

    print '@a = ''' + @a + ''''

    2013年6月17日 16:01
  • select @s='@a=''' + @A + ''',@b=''' + @B + ''''
    • 已建议为答案 lynn磷 2013年6月18日 2:16
    • 取消建议作为答案 zyyjc 2013年6月18日 3:46
    2013年6月18日 1:04
  • 楼上几位的方法是固定的,需要在每个存储过程中都要写,感觉很麻烦.我在想是否有通用的方法在存储过程中能动态的获取不同存储过程的参数及传入的参数值,这样做的目的是为了存储过程执行错误的时候,我就可以很清楚是执行什么语句出现的问题了.

    sys.parameters这个系统表能取到存储过程的参数,可是如何获取到参数值呢?请大家帮帮忙,谢谢!


    • 已编辑 zyyjc 2013年6月18日 3:56
    2013年6月18日 3:54
  • 关键是 SQL Server 的存储过程本身就不支持动态参数, 你在存储中又怎么去动态呢?

    2013年6月18日 5:24
  • 我是这样写的,不过需要将传入的参数的形式是这样:exec up_test '5,6,1' 

    即是: up_test '参数1,参数2,参数3' 用逗号来分隔

    不知道符不符合LZ的要求,需要创建一个字符串分割函数f_split,当然传入进去存储过程的参数是字符串

    LZ可以分割开之后转换为其他类型

    USE [pratice]
    GO
    ---------------------------------
    
    DROP FUNCTION [dbo].[f_split]
    GO
    CREATE FUNCTION f_split
    (
      @SourceSql VARCHAR(8000) ,
      @StrSeprate VARCHAR(10)
    )
    RETURNS @temp TABLE ( ss VARCHAR(100) )
    AS
        BEGIN
            DECLARE @i INT
            SET @SourceSql = RTRIM(LTRIM(@SourceSql))
            SET @i = CHARINDEX(@StrSeprate, @SourceSql)
            WHILE @i >= 1
                BEGIN
                    INSERT  @temp
                    VALUES  ( LEFT(@SourceSql, @i - 1) )
                    SET @SourceSql = SUBSTRING(@SourceSql, @i + 1,
                                               LEN(@SourceSql) - @i)
                    SET @i = CHARINDEX(@StrSeprate, @SourceSql)
                END
            IF @SourceSql <> '\'
                INSERT  @temp
                VALUES  ( @SourceSql )
            RETURN
        END
    
    
    ------------------------------------
    
    CREATE   proc up_test (@a varchar(100))
    AS
    DECLARE @s VARCHAR(200)
    SET @s=' '
    DECLARE @num INT
    DECLARE @increase INT
    DECLARE @temps VARCHAR(20)
    CREATE TABLE temptb(id INT IDENTITY(1,1) NOT NULL,para VARCHAR(20))
    INSERT INTO temptb(para) SELECT ss FROM [f_split](@a,',')
    SELECT  @num = COUNT(*)
    FROM    temptb
    SET @increase = 1
    WHILE @increase < @num +1
        BEGIN
            SELECT  @temps = para
            FROM    temptb
            WHERE   id = @increase;
            SET @s = @s +' 参数'+CAST(@increase AS VARCHAR(20))+':  '+ @temps+';'
            SET @increase = @increase + 1
        END 
    SELECT  @s
    DROP TABLE temptb
    
    exec up_test '库存,6,2013-6-12' 

    2013年6月18日 5:27
  • 关键是 SQL Server 的存储过程本身就不支持动态参数, 你在存储中又怎么去动态呢?

    具体实现我也不太清楚,也是希望能达到我这样的要求.便于调试错误,请问下邹大哥,如果存储过程执行错误的话,有什么办法能知道执行的是哪个存储过程和传递的参数值呢?
    2013年6月18日 5:34
  • 我是这样写的,不过需要将传入的参数的形式是这样:exec up_test '5,6,1' 

    即是: up_test '参数1,参数2,参数3' 用逗号来分隔

    不知道符不符合LZ的要求,需要创建一个字符串分割函数f_split,当然传入进去存储过程的参数是字符串

    LZ可以分割开之后转换为其他类型

    USE [pratice]
    GO
    ---------------------------------
    
    DROP FUNCTION [dbo].[f_split]
    GO
    CREATE FUNCTION f_split
    (
      @SourceSql VARCHAR(8000) ,
      @StrSeprate VARCHAR(10)
    )
    RETURNS @temp TABLE ( ss VARCHAR(100) )
    AS
        BEGIN
            DECLARE @i INT
            SET @SourceSql = RTRIM(LTRIM(@SourceSql))
            SET @i = CHARINDEX(@StrSeprate, @SourceSql)
            WHILE @i >= 1
                BEGIN
                    INSERT  @temp
                    VALUES  ( LEFT(@SourceSql, @i - 1) )
                    SET @SourceSql = SUBSTRING(@SourceSql, @i + 1,
                                               LEN(@SourceSql) - @i)
                    SET @i = CHARINDEX(@StrSeprate, @SourceSql)
                END
            IF @SourceSql <> '\'
                INSERT  @temp
                VALUES  ( @SourceSql )
            RETURN
        END
    
    
    ------------------------------------
    
    CREATE   proc up_test (@a varchar(100))
    AS
    DECLARE @s VARCHAR(200)
    SET @s=' '
    DECLARE @num INT
    DECLARE @increase INT
    DECLARE @temps VARCHAR(20)
    CREATE TABLE temptb(id INT IDENTITY(1,1) NOT NULL,para VARCHAR(20))
    INSERT INTO temptb(para) SELECT ss FROM [f_split](@a,',')
    SELECT  @num = COUNT(*)
    FROM    temptb
    SET @increase = 1
    WHILE @increase < @num +1
        BEGIN
            SELECT  @temps = para
            FROM    temptb
            WHERE   id = @increase;
            SET @s = @s +' 参数'+CAST(@increase AS VARCHAR(20))+':  '+ @temps+';'
            SET @increase = @increase + 1
        END 
    SELECT  @s
    DROP TABLE temptb
    
    exec up_test '库存,6,2013-6-12' 

    感谢您的热心回复,你的这种方式我也考虑过,不过这种方式会导致传入的参数值不明确,并且需要在存储过程中拆分对应不同的值,感觉并不是很好的解决方式
    2013年6月18日 5:37
  • 其实我的目的就是当执行存储过程出错的时候,能知道是执行了哪个存储过程和参数的值,这样便于排查错误,仅此而已!不知道各位是怎么处理这种情况的?
    2013年6月18日 5:40
  • 一般在调用程序上去处理, 出错记录会同时包含调用的语句和具体的参数值

    存储过程中, 估计你的想法是弄一个通用的 try ... catch 中的 catch 块错误处理吧,在这个处理中可以自动把当前存储过程的参数值给存储起来, 这个在sql server 中应该是没办法做的 

    • 已标记为答案 zyyjc 2013年9月23日 10:17
    2013年6月18日 6:31
  • 一般在调用程序上去处理, 出错记录会同时包含调用的语句和具体的参数值

    存储过程中, 估计你的想法是弄一个通用的 try ... catch 中的 catch 块错误处理吧,在这个处理中可以自动把当前存储过程的参数值给存储起来, 这个在sql server 中应该是没办法做的 

    是的,想弄个通用的异常捕捉模块.在调用程序上不好实现,因为存储过程中已经捕捉了,调用程序是不会报出异常的.



    • 已编辑 zyyjc 2013年6月23日 3:41 dddd
    2013年6月23日 3:41
  • 查询数据字典中的参数拼接即可

    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com

    2013年6月24日 1:44
  • 查询数据字典中的参数拼接即可

    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com

    这是可以得到参数名称, 但无法通过这个名称得到值
    2013年6月24日 2:09
  • 查询数据字典中的参数拼接即可

    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com

    通过系统表是可以获取参数,但是如何能获取参数的值呢?
    2013年6月27日 10:34