2014-04-09 63 views
17

我有一个存储过程需要两个参数。我可以在Server Management Studio中成功执行它。它显示了我所期望的结果。但它也会返回一个返回值。SQL服务器存储过程返回一个表

它已加入这一行,

SELECT 'Return Value' = @return_value 

我想在存储过程返回它显示我在成绩表中还不如我打电话从MATLAB这个存储过程和所有它返回的返回值是真的还是假的。

我是否需要在我的存储过程中指定它应该返回的内容?如果是的话,我该如何指定一个4列的表(varchar(10),float,float,float)?

回答

37

过程不能像这样返回表。然而,你可以从表中的程序像这样的选择并指导其为表(或表变量):

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

我建议看到[**这**](http://stackoverflow.com/questions/5604927/how-to-return-a-table-from-stored-procedure)溶液为好。人们会直觉地认为这是行不通的,但确实如此,这是最简单的方法。 – Veverke

-1

这里有一个SP,这两个返回表和返回值的例子。我不知道你是否需要返回“返回值”,我不知道MATLAB和它的要求。

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

,如果你愿意,你可以使用一个输出参数,而不是返回值的两个结果集和返回值

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

由一个存储过程返回的状态值只能是INT数据类型。您不能在RETURN语句中返回其他数据类型。

Lesson 2: Designing Stored Procedures来自:

每个存储过程可以返回称为 执行状态值的整数值或返回代码。

如果您仍然希望从SP返回表,您必须处理从SP中的SELECT返回的记录集或绑定到传递XML数据类型的OUTPUT变量。

HTH,

约翰

4

考虑创建可返回一个表,并在查询中使用的功能。

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

一个函数和一个过程之间的主要区别在于一个函数使得不改变的任何表。它只返回一个值。

在这个例子中,我创建了一个查询来给我一个给定表中不为空或空的所有列的计数。

有可能有很多方法来清理它。但它很好地说明了一个功能。

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 

然后用

SELECT * FROM usp_listFields('Employees') 

执行该函数产生许多像的行:

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

脚本中存在两个错误: - 在存储过程中,必须省略最后一个UNION。因此,执行第三个代码片段会出现错误,可以通过删除最后一个UNION来解决该错误。 - 在调用usp_listFields的第二段代码中,您必须提供参数模式和表格。 – Jan

+0

如果您想了解有关返回值,设置输出变量和返回更复杂数据(如完整表格)的更多信息,请查看https://www.youtube.com/playlist?list=PLNIs-AWhQzcleQWADpUgriRxebMkMmi4H上的这些优秀教程 – Jan

2

我有类似的情况,通过使用过程内临时表解决,与原始存储过程返回相同的字段:

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''' 

插入件插入@T EXEC [主] .dbo.sp_executesql @q 获取下一个从@data 成@ C,@ b 端 靠近@data DEALLOCATE @data SELECT * FROM @T 返回 结束

2

我经常使用表类型来确保更一致性和简化代码。您无法从技术上返回“表格”,但可以返回结果集并使用语法,您可以清楚地调用PROC并将结果存储到表格类型中。在下面的例子中,我实际上是将一个表传递给一个PROC以及另一个需要添加逻辑的参数,然后我有效地“返回一个表”,然后可以将它作为表变量使用。

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