none
procedure dinamiche e parametri di output RRS feed

  • Domanda

  • che voi sappiate è possibile scrivere una procedura parametrica in TSQL e fare in modo che  restiruisca valori in output ?? 


    claudio cannella

    venerdì 2 ottobre 2020 19:00

Risposte

Tutte le risposte

  • Ciao Claudio,

    certamente, qui trovi documentazione ed esempi:

    https://docs.microsoft.com/it-it/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure

    Ciao!


    Sergio Govoni

    Microsoft Data Platform MVP | MVP Profile | English Blog | Twitter | LinkedIn

    venerdì 2 ottobre 2020 21:39
    Moderatore
  • Ciao,

    è possibile anche per le procedure che eseguono codice dinamico: sp_executesql

    G.

    • Contrassegnato come risposta opaklaus sabato 30 gennaio 2021 17:35
    sabato 3 ottobre 2020 07:52
  • per edoardo : siate cortese o anziano  lasciate che sia io a stabilire e segnare se un post nel thread rispondi compiutamente e intelligibilmente alla mia domanda  anche se a volte ci imp;iego diversi giorni [ questo dipende semplicemente dal tempo che mi lasciano per svolgere il mio incarico proimario di sviluppatore

    venerdì 9 ottobre 2020 07:00
  • Buona sera a tutti e a sergio in particolare 

    ho seguito le indicazioni che mi avete dato e quelle del manuale 

    il risultato è  stato  questo 

    declare @ricev int 
    exec sp_executesql 
    N'listastorico' ,
    N'@tpev NVARCHAR(20), @prout int output,@debug bit',
    @tpev=N'%creat%', @prout=@ricev OUTPUT, @debug=0;
    select @ricev as 'risultato'

    il risultato della chiamata è «Messaggio 201, livello 16, stato 4, procedura listastorico, riga 0

    La procedura o funzione 'listastorico' prevede il parametro '@tpev', che non è stato specificato.

    »

    sapete dove risede l'errore ?? ' 

    eventualemntte posso postare anche laa procedura chiamata


    claudio cannella

    sabato 13 febbraio 2021 20:13
  • Ciao Claudio,

    ho riprodotto l'errore con una stored procedure di esempio:

    DROP PROCEDURE IF EXISTS dbo.sp_listastorico;
    GO
    
    CREATE PROCEDURE dbo.sp_listastorico
      @tpev NVARCHAR(20)
      ,@debug BIT
      ,@prout INTEGER OUTPUT
    AS BEGIN
      PRINT ('Input Parameters:')
      PRINT ('@tpev = ' + @tpev);
      PRINT ('@prout = ' + LTRIM(RTRIM(STR(@prout))));
      PRINT ('@debug = ' + LTRIM(RTRIM(STR(@debug))))
    
      SET @prout = 21;
      PRINT ('Output Parameter:');
      PRINT ('@prout = ' + LTRIM(RTRIM(STR(@prout))))
      RETURN
    END;
    GO


    Per il momento ti propongo di utilizzare la chiamata diretta alla stored procedure:

    DECLARE @ricev INTEGER = 0
    EXEC dbo.sp_listastorico
      @tpev = N'%creat%'
      ,@debug = 0
      ,@prout = @ricev OUTPUT;
    PRINT LTRIM(RTRIM(STR(@ricev)))

    Che stampa il seguente output:

    Input Parameters:
    @tpev = %creat%
    @prout = 0
    @debug = 0
    Output Parameter:
    @prout = 21
    21

    Conto di riuscire ad approfondire nei prossimi giorni..

    Ciao!


    Sergio Govoni

    Microsoft Data Platform MVP | MVP Profile | English Blog | Twitter | LinkedIn


    sabato 20 febbraio 2021 14:42
    Moderatore
  • Ciao Claudio,

    ho approfondito il caso, con un parametro di output e l'utilizzo di sp_executesql il comando EXECUTE dovrà avere questa forma:

    DECLARE @ricev INTEGER = 0
    EXEC sp_executesql
      N'dbo.sp_listastorico @tpev, @debug, @prout OUTPUT'
      , N'@tpev NVARCHAR(20), @debug BIT, @prout INTEGER OUTPUT'
      , @tpev = N'%creat%'
      , @debug = 0
      , @prout = @ricev OUTPUT
    SELECT @ricev AS 'Result';
    GO

    Con la stored procedure di esempio che ho postato ieri sera otterrai questo risultato:

    Input Parameters:
    @tpev = %creat%
    @prout = 0
    @debug = 0
    Output Parameters:
    @prout = 21
    Result
    -----------
    21
    

    E' buona pratica tenere per ultimi eventuali parametri di output.

    Ciao!


    Sergio Govoni

    Microsoft Data Platform MVP | MVP Profile | English Blog | Twitter | LinkedIn



    domenica 21 febbraio 2021 10:49
    Moderatore
  • grazie - domani ci provo poi ti so dire 

    K


    claudio cannella

    lunedì 22 febbraio 2021 21:11
  • sì ma la domanda era  perchè mi segna assente il parametro di ingresso @tpev 

    perchè questo causa un errore di compilazione che impedisce l'esecuzione 

    provo con la tua procedura  di test 

    k


    claudio cannella

    martedì 2 marzo 2021 15:14
  • Ciao,

    il problema è che il passaggio dei parametri dalla sp_executesql alla stored procedure listastorico non è definito:

    exec sp_executesql 
    	@stmt = N'listastorico @tpev= @P0, @prout = @P1, @debug = @P2' ,
    	@params = N'@P1 int output, @P2 bit, @P0 NVARCHAR(20)',
    	@P1 = @ricev OUTPUT, 
    	@P0 = N'%creat%', 
    	@P2 = 0;
    

    Nota che ho "rimescolato" i vari @P0.. per evidenziare il fatto che il passasggio avviene by name e non by position.

    O anche:

    exec sp_executesql 
    	N'exec dbo.listastorico @tpev= @tpev, @prout= @prout, @debug = @debug',
    	N'@tpev NVARCHAR(20), @prout int output,@debug bit',
    	@tpev= N'%creat%', 
    	@prout= @ricev OUTPUT, 
    	@debug= 0;

    Quindi puoi anche chiamare i parametri "esterni", ovvero quelli della sp_executesql, come quelli interni della listastorico: ciò non toglie che nel primo parametro - 'exec dbo.listapratiche ...' - li devi sempre assegnare; sql non li mappa in quanto sei tu responsabile dell'assegnazione dei parametri alla tua stored proc.

    G.


    martedì 2 marzo 2021 16:09
  • quindi sembra che il problema si risolva  specificando la lista intera dei parametri anche nella stringa  che contiene il nome delle procedura 

    in effetti alla prova fatto come dici tu funziona  in diretta ma  questa impostazione 

    proc [dbo].[listastorico] 
    @tpev nvarchar(20),
    @debug bit =1,
    @prout int output
    as 
    declare @sqt nvarchar(max), @sql nvarchar(max) , @ritorno int 
    set @sqt=' use[testdb]
    declare @tav nvarchar(80), @cmd nvarchar(200),@data datetime2, @rel tinyint 
    declare @ver tinyint,@bui smallint,@prout int
    declare cursto cursor for select descri,[DDLCommand],data ,[release] ,[versione],[build]
    from storicodb where DDLCommand like ''%PRM%''
    open cursto
    print ''eventi di tipo PRM'' 
    print ''     data      | tabella | comando    | release|versione| build ''
    fetch next from cursto into @tav, @cmd,@data, @rel,@ver,@bui
    while @@fetch_status>=0
    begin
    print convert (varchar(30) , @data,126) +'' | ''+@tav+'' | ''+@cmd+'' | ''+cast(@rel as varchar(5))+'' | ''+ cast(@ver as varchar(5))+'' | ''+cast(@bui as varchar(5))+'' |''
    fetch next from cursto into @tav, @cmd,@data ,@rel,@ver,@bui
    END 
    close  cursto
    deallocate cursto 
    select @prout =5
    return '
    set @SQL = replace (@sqt,'PRM',@tpev )
    if @debug= 1 
    print @sql 
    /*else 
    begin 
    declare @result int 
    set @sql = @sql+N' @tpev,@debug,@prout OUTPUT' 
    exec sp_executesql  @sql,
    N'@tpev nvarchar(20), @debug bit, @prout int OUTPUT',
    @tpev=N'%creat',@debug=0,@prout=@result output

    end */

    trova errori sia con che  senza l'else dell'if finale 

     mi piacerebbe uscirci 

    K


    claudio cannella

    martedì 2 marzo 2021 16:26
  • Dovresti magari aprire un altro thread riportando oltre alla procedura l'errore che ricevi e come la ingaggi.

    G.

    martedì 2 marzo 2021 17:36