Конференция "Базы" » как внутри процедуры MSSQL узнать значения всех ее переменных ?
 
  • ВладОшин © (03.07.17 17:08) [0]
    т.е. этой же процедуры.
    При этом, код должен быть универсален, т.е. копипастнул его в другую процедуру, и он там также определит значения параметров (и, допустим, запишет cast as varchar в ..куда-то)

    т.е. есть
    proc1  @DV datetime
    proc2  @CV varchar(99)
    proc2  @IV int, возможно еще параметр(ы)

    и нужно написать некое {x}, которое правильно отработает и в первой и во второй(и 3ей), без изменения.

    какие мои мысли
    1. по @@PROCID получить имя процедуры  OBJECT_NAME(@@PROCID)

    2. получить параметры
    select
         PName =  c.name ,
         PType =   t.name,
         PLen = c.length
     from syscolumns c
     join sysobjects o on o.id = c.id
     join systypes t on t.xtype = c.xtype
    where o.xtype = 'P'
     and o.name = 'процедура' -- OBJECT_NAME(@@PROCID)

    3. ?
    Динамик sql через sp_executesql с параметром равным параметры с шага 2?
  • ВладОшин © (03.07.17 17:15) [1]
    Отставить переменных - параметров
    >> внутри процедуры MSSQL узнать значения всех ее параметров
  • ВладОшин © (03.07.17 19:13) [2]
    что-то не получается )
    обязательно надо руками указать переменную

    фактически надо сделать select ByNameIfExists('@V')

    допустим,
    declare @V1 int = 11, @V2 int = 22
    declare @mysql nvarchar(4000)
    set @mysql = 'set @V1 = @V1 + @V2'
    exec sp_executesql @mysql, N'@V1 int out, @V2 int out', @V1 = @V1 out, @V2 = @V2 out
    select @V1, @V2

    33 и 22 выводит, например..

    допустим еще раз обернем в Exec

    declare @SQL nvarchar(4000) = '
    declare @V1 int = 11, @V2 int = 22
    declare @mysql nvarchar(4000)
    set @mysql = ''set @V1 = @V1 + @V2''
    exec sp_executesql @mysql, N''@V1 int out, @V2 int out'', @V1 = @V1 out, @V2 = @V2 out
    select @V1, @V2'
    exec (@SQL)

    33 и 22 выводит опять

    и все.. как туда воткнуть "по-ссылке" кроме как явно указывать ..
    - не получается.
  • rrrrrr © (03.07.17 19:19) [3]
    в цикле по параметрам склеить через union all
    'select ' + @parName + ' as pname, ' + @pName + ' as value'

    отдать это sp_executesql он вернет роусет
  • ВладОшин © (03.07.17 19:25) [4]
    Спасибо,
    но нет.. не получится, наверное
    для exec sp_executesql придется все равно написать явно все параметры
  • ВладОшин © (03.07.17 19:30) [5]
    или я не догоняю
    не могли бы подсказать, если так?

    create PROCEDURE proc_PrintMyParams
    @I int = 123
    AS
    BEGIN
    SET NOCOUNT ON;
    print 'DIRECT ------------------------------'
    print '@I = '+cast(@I as varchar);
    print ' ------------------------------DIRECT'

    declare @T table (PName varchar(99), PType varchar(99), PLen int)
    insert into @T
    select
        PName =  c.name ,
        PType =   t.name,
        PLen = c.length
    from syscolumns c
    join sysobjects o on o.id = c.id
    join systypes t on t.xtype = c.xtype
    where o.xtype = 'P'
    and o.name = OBJECT_NAME(@@PROCID)

    declare @SQL nvarchar(4000) = '', @Param nvarchar(4000) = '';

    select @SQL = @SQL + 'print cast(' + PName + ' as varchar) ' + char(13) from @T
    print @SQL

    exec sp_executesql @SQL, ?как?

    return
    END
    GO
  • rrrrrr © (03.07.17 19:31) [6]
    не надо никаких параметров
    вот это вот возвращает одну строку
    execute sp_executesql(N'select getdate() as xxx')

    надо просто склеить
    select @p1
    union all
    select @p1
    ....
    union all
    select @pn

    ну и добавить сами имена возможно зареплейсив в них собаку
  • ВладОшин © (03.07.17 19:36) [7]
    да нет,
    execute sp_executesql(N'select getdate() as xxx')
    не обращается на область видимости выше себя

    а надо к переменной обратиться, которая не определена внутри блока sp_executesql
    ее можно туда сунуть, если явно указать, напрмер, но тогда зачем этот огород, можно явно и так указать..
  • rrrrrr © (03.07.17 20:03) [8]
    Единственный гемор - кавычки для строк

    CREATE PROCEDURE test (@p1 nvarchar(255))
    AS
    declare @dyn_sql nvarchar(max);
    BEGIN
    set @dyn_sql = N'select ''' + @p1 + ''' as pvalue';
    execute sp_executesql @stmt = @dyn_sql;
    END;

    execute dbo.test @p1 = N'куку емае'
  • rrrrrr © (03.07.17 20:12) [9]
    тоисть
    если убрать крайние кавычки с динамик sql и рассматривать текст запроса в контексте tsql/sql
    то мы тупо селектим литералы значений параметров
  • ВладОшин © (03.07.17 20:33) [10]
    @p1 в вашем примере указан опять явно
    оператор set его видит не как литералы, а как определенную переменную в поле своей видимости

    не используйте @p1 вообще, получите его имя и попробуйте - не получится, скорее всего
 
Конференция "Базы" » как внутри процедуры MSSQL узнать значения всех ее переменных ?
Есть новые Нет новых   [134427   +34][b:0][p:0]