2014-04-09 19 views
17

Ho una stored procedure che accetta due parametri. Posso eseguirlo con successo in Server Management Studio. Mi mostra i risultati che sono come mi aspetto. Tuttavia restituisce anche un valore di ritorno.La stored procedure del server SQL restituisce una tabella

E ha aggiunto questa linea,

SELECT 'Return Value' = @return_value 

Vorrei la stored procedure per restituire il tavolo mi mostra nei risultati non il valore restituito come io chiamo questa stored procedure da MATLAB e tutto ritorna è vero o falso.

Devo specificare nella procedura memorizzata cosa dovrebbe restituire? In tal caso, come posso specificare una tabella di 4 colonne (varchar (10), float, float, float)?

risposta

37

Una procedura non può restituire una tabella come tale. Tuttavia è possibile selezionare da una tabella in una procedura e dirigerla in un (variabile o tabella) tabella come questa:

create procedure p_x 
as 
begin 
declare @t table(col1 varchar(10), col2 float, col3 float, col4 float) 
insert @t values('a', 1,1,1) 
insert @t values('b', 2,2,2) 

select * from @t 
end 
go 

declare @t table(col1 varchar(10), col2 float, col3 float, col4 float) 
insert @t 
exec p_x 

select * from @t 
+4

vi consiglio di vedere la soluzione [** questa **] (http://stackoverflow.com/questions/5604927/how-to-return-a-table-from-stored-procedure) pure. Uno penserebbe intuitivamente che non funzionerebbe, ma lo fa, rendendolo il modo più semplice per farlo. – Veverke

-1

Ecco un esempio di un SP che sia restituisce una tabella e un valore di ritorno. Non so se è necessario il ritorno del "Valore di ritorno" e non ho idea di MATLAB e di ciò che richiede.

CREATE PROCEDURE test 
AS 
BEGIN 

    SELECT * FROM sys.databases 

    RETURN 27 
END 

--Use this to test 
DECLARE @returnval int 

EXEC @returnval = test 

SELECT @returnval 
3

È possibile utilizzare un parametro out al posto del valore di ritorno, se si desidera utilizzare entrambi i set di risultati e un valore di ritorno

CREATE PROCEDURE proc_name 
@param int out 
AS 
BEGIN 
    SET @param = value 
SELECT ... FROM [Table] WHERE Condition 
END 
GO 
2

il valore di stato viene restituito da una stored procedure può essere solo un INT tipo di dati. Non è possibile restituire altri tipi di dati nell'istruzione RETURN.

Da Lesson 2: Designing Stored Procedures:

Ogni stored procedure può restituire un valoreinteger noto come valore di stato esecuzione o un codice di ritorno.

Se si desidera ancora una tabella restituita dall'SP, sarà necessario lavorare il set di record restituito da una SELECT all'interno dell'SP o legare in una variabile OUTPUT che passa un tipo di dati XML.

HTH,

John

4

consideri la creazione di una funzione che può restituire un tavolo e possono essere usate in una query.

https://msdn.microsoft.com/en-us/library/ms186755.aspx

La differenza principale tra una funzione e una procedura è che una funzione non modifica alcuna tabella. Restituisce solo un valore.

In questo esempio sto creando una query per darmi i conteggi di tutte le colonne in una data tabella che non sono nulle o vuote.

Ci sono probabilmente molti modi per ripulirlo. Ma illustra bene una funzione.

USE Northwind 

CREATE FUNCTION usp_listFields(@schema VARCHAR(50), @table VARCHAR(50)) 
RETURNS @query TABLE (
    FieldName VARCHAR(255) 
    ) 
BEGIN 
    INSERT @query 
    SELECT 
     'SELECT ''' + @table+'~'+RTRIM(COLUMN_NAME)+'~''+CONVERT(VARCHAR, COUNT(*)) '+ 
    'FROM '[email protected]+'.'[email protected]+' '+ 
      ' WHERE isnull("'+RTRIM(COLUMN_NAME)+'",'''')<>'''' UNION' 
    FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table and TABLE_SCHEMA = @schema 
    RETURN 
END 

poi eseguire la funzione con

SELECT * FROM usp_listFields('Employees') 

produce un numero di righe come:

SELECT 'Employees~EmployeeID~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("EmployeeID",'')<>'' UNION 
SELECT 'Employees~LastName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("LastName",'')<>'' UNION 
SELECT 'Employees~FirstName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("FirstName",'')<>'' UNION 
+0

Due errori negli script: -Nella stored procedure, l'ultimo UNION deve essere omesso. Quindi l'esecuzione del terzo pezzo di codice dà un errore, che può essere risolto rimuovendo l'ultimo UNION. -Nel secondo pezzo di codice quando chiamate usp_listFields DEVI fornire sia argomenti schema che tabella. – Jan

+0

Se vuoi saperne di più sulla restituzione dei valori, impostare le variabili di output e restituire dati più complessi come le tabelle complete, consulta questi tutorial eccellenti su https://www.youtube.com/playlist?list=PLNIs-AWhQzcleQWADpUgriRxebMkMmi4H – Jan

2

avevo una situazione simile e risolto utilizzando una tabella temporanea all'interno della procedura, con gli stessi campi restituiti dalla stored procedure originale:

CREATE PROCEDURE mynewstoredprocedure 
AS 
BEGIN 

INSERT INTO temptable (field1, field2) 
EXEC mystoredprocedure @param1, @param2 

select field1, field2 from temptable 

-- (mystoredprocedure returns field1, field2) 

END 
0
create procedure PSaleCForms 
as 
begin 
declare 
@b varchar(9), 
@c nvarchar(500), 
@q nvarchar(max) 
declare @T table(FY nvarchar(9),Qtr int,title nvarchar (max),invoicenumber  nvarchar(max),invoicedate datetime,sp decimal 18,2),grandtotal decimal(18,2)) 
declare @data cursor 
set @data= Cursor 
forward_only static 
for 
select x.DBTitle,y.CurrentFinancialYear from [Accounts  Manager].dbo.DBManager x inner join [Accounts Manager].dbo.Accounts y on  y.DBID=x.DBID where x.cfy=1 
open @data 
fetch next from @data 
into @c,@b 
while @@FETCH_STATUS=0 
begin 
set @q=N'Select '''[email protected]+''' [fy], case cast(month(i.invoicedate)/3.1 as int)  when 0 then 4 else cast(month(i.invoicedate)/3.1 as int) end [Qtr],  l.title,i.invoicenumber,i.invoicedate,i.sp,i.grandtotal from  ['[email protected]+'].dbo.invoicemain i inner join ['[email protected]+'].dbo.ledgermain l on  l.ledgerid=i.ledgerid where (sp=0 or stocktype=''x'') and invoicetype=''DS''' 

inserto in @T exec [master] .dbo.sp_executesql @q prendere prossimo da @data in @ c, b @ fine vicino @data deallocare @data select * from @T return end

2

Lo faccio spesso utilizzando i tipi di tabella per garantire maggiore coerenza e semplificare il codice. Non è possibile restituire tecnicamente "una tabella", ma è possibile restituire un set di risultati e utilizzando la sintassi , è possibile chiamare chiaramente un PROC e memorizzare i risultati in un tipo di tabella. Nell'esempio che segue sto effettivamente passando una tabella in una PROC insieme ad un'altra param devo aggiungere la logica, quindi in effetti sto "restituendo una tabella" e posso quindi lavorare con quella come variabile di tabella.

/****** Check if my table type and/or proc exists and drop them ******/ 
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'returnTableTypeData') 
DROP PROCEDURE returnTableTypeData 
GO 
IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = 'myTableType') 
DROP TYPE myTableType 
GO 

/****** Create the type that I'll pass into the proc and return from it ******/ 
CREATE TYPE [dbo].[myTableType] AS TABLE(
    [someInt] [int] NULL, 
    [somenVarChar] [nvarchar](100) NULL 
) 
GO 

CREATE PROC returnTableTypeData 
    @someInputInt INT, 
    @myInputTable myTableType READONLY --Must be readonly because 
AS 
BEGIN 

    --Return the subset of data consistent with the type 
    SELECT 
     * 
    FROM 
     @myInputTable 
    WHERE 
     someInt < @someInputInt 

END 
GO 


DECLARE @myInputTableOrig myTableType 
DECLARE @myUpdatedTable myTableType 

INSERT INTO @myInputTableOrig (someInt,somenVarChar) 
VALUES (0, N'Value 0'), (1, N'Value 1'), (2, N'Value 2') 

INSERT INTO @myUpdatedTable EXEC returnTableTypeData @someInputInt=1, @[email protected] 

SELECT * FROM @myUpdatedTable 


DROP PROCEDURE returnTableTypeData 
GO 
DROP TYPE myTableType 
GO 
Problemi correlati