it-swarm.com.de

Die gespeicherte Prozedur von SQL Server gibt eine Tabelle zurück

Ich habe eine gespeicherte Prozedur, die zwei Parameter aufnimmt. Ich kann es erfolgreich in Server Management Studio ausführen. Es zeigt mir die Ergebnisse, die ich erwartet habe. Es gibt jedoch auch einen Rückgabewert zurück.

Es hat diese Zeile hinzugefügt,

 SELECT 'Return Value' = @return_value

Ich möchte, dass die gespeicherte Prozedur die Tabelle zurückgibt, die in den Ergebnissen angezeigt wird, nicht den Rückgabewert, da ich diese gespeicherte Prozedur von MATLAB aus aufrufe und alles, was zurückgegeben wird, true oder false ist.

Muss ich in meiner gespeicherten Prozedur angeben, was zurückgegeben werden soll? Wenn ja, wie gebe ich eine Tabelle mit 4 Spalten an (varchar (10), float, float, float)?

27
mHelpMe

Eine Prozedur kann keine Tabelle als solche zurückgeben. Sie können jedoch aus einer Tabelle in einer Prozedur auswählen und diese wie folgt in eine Tabelle (oder Tabellenvariable) umleiten:

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
59
t-clausen.dk

Erstellen Sie eine Funktion, die eine Tabelle zurückgeben und in einer Abfrage verwenden kann.

https://msdn.Microsoft.com/de-de/library/ms186755.aspx

Der Hauptunterschied zwischen einer Funktion und einer Prozedur besteht darin, dass eine Funktion keine Änderungen an einer Tabelle vornimmt. Es wird nur ein Wert zurückgegeben.

In diesem Beispiel erstelle ich eine Abfrage, um die Anzahl aller Spalten in einer bestimmten Tabelle anzuzeigen, die nicht null oder leer sind.

Es gibt wahrscheinlich viele Möglichkeiten, dies aufzuräumen. Aber es veranschaulicht eine Funktion gut.

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

Dann die Funktion mit ausführen 

SELECT * FROM usp_listFields('Employees')

produziert eine Reihe von Zeilen wie:

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
5
Algonaut

Ich mache dies häufig mit Tabellentypen, um mehr Konsistenz zu gewährleisten und Code zu vereinfachen. Sie können zwar technisch keine "Tabelle" zurückgeben, aber Sie können eine Ergebnismenge zurückgeben. Mit der INSERT INTO .. EXEC ...-Syntax können Sie einen PROC eindeutig aufrufen und die Ergebnisse in einem Tabellentyp speichern. Im folgenden Beispiel übergebe ich tatsächlich eine Tabelle in einen PROC, zusammen mit einem anderen Parameter, den ich zum Hinzufügen von Logik verwenden muss. Dann "füge ich tatsächlich eine Tabelle zurück" und kann dann als Tabellenvariable damit arbeiten.

/****** 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
5
rainabba

Sie können einen Out-Parameter anstelle des Rückgabewerts verwenden, wenn Sie sowohl eine Ergebnismenge als auch einen Rückgabewert wünschen

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

Ich hatte eine ähnliche Situation und löste mich durch Verwendung einer temporären Tabelle in der Prozedur, wobei die gleichen Felder von der ursprünglichen gespeicherten Prozedur zurückgegeben wurden:

CREATE PROCEDURE mynewstoredprocedure
AS 
BEGIN

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

select field1, field2 from temptable

-- (mystoredprocedure returns field1, field2)

END
2
Cassio Veras

Der Statuswert, der von einer gespeicherten Prozedur zurückgegeben wird, kann nur ein INT-Datentyp sein. Sie können keine anderen Datentypen in der RETURN-Anweisung zurückgeben.

Aus Lektion 2: Gespeicherte Prozeduren entwerfen :

Jede gespeicherte Prozedur kann einen integer -Wert zurückgeben, der als .__ bezeichnet wird. Ausführungsstatuswert oder Rückkehrcode.

Wenn Sie dennoch möchten, dass eine Tabelle vom SP zurückgegeben wird, müssen Sie entweder den Datensatz bearbeiten, der von einem SELECT innerhalb von SP zurückgegeben wurde, oder in eine OUTPUT-Variable einbinden, die einen XML-Datentyp übergibt.

HTH,

John

2
John Eisbrener
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'''

fügen Sie in @T exec [master] .dbo.sp_executesql @q . holen Sie als nächstes von @data Wählen Sie * aus @T Rückkehr Ende aus 

0
Rohit