SQL Server存储过程返回一个表

时间:2014-04-09 13:23:48

标签: sql sql-server matlab stored-procedures

我有一个存储过程,它接受两个参数。我可以在Server Management Studio中成功执行它。它向我展示了我期望的结果。但是它也会返回一个返回值。

已添加此行,

 SELECT 'Return Value' = @return_value

我希望存储过程返回它在结果中显示的表而不是返回值,因为我从MATLAB调用此存储过程,并且它返回的全部为true或false。

我是否需要在我的存储过程中指定它应该返回什么?如果是这样,我如何指定一个包含4列的表(varchar(10),float,float,float)?

9 个答案:

答案 0 :(得分:65)

程序无法返回表格。但是,您可以从过程中的表中进行选择,并将其指向表格(或表变量),如下所示:

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

答案 1 :(得分:5)

考虑创建一个可以返回表并在查询中使用的函数。

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 '+@schema+'.'+@table+' '+
          ' 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

答案 2 :(得分:5)

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

/****** 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, @myInputTable=@myInputTableOrig

SELECT * FROM @myUpdatedTable


DROP PROCEDURE returnTableTypeData
GO
DROP TYPE myTableType
GO

答案 3 :(得分:3)

如果您想要结果集和返回值

,则可以使用out参数而不是返回值
CREATE PROCEDURE proc_name 
@param int out
AS
BEGIN
    SET @param = value
SELECT ... FROM [Table] WHERE Condition
END
GO

答案 4 :(得分:3)

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

来自Lesson 2: Designing Stored Procedures

  

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

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

HTH,

约翰

答案 5 :(得分: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

答案 6 :(得分: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 '''+@b+''' [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     ['+@c+'].dbo.invoicemain i inner join  ['+@c+'].dbo.ledgermain l on     l.ledgerid=i.ledgerid where (sp=0 or stocktype=''x'') and invoicetype=''DS'''

插入@T exec [master] .dbo.sp_executesql @q 从@data获取下一个 进入@ c,@ b 结束 关闭@data deallocate @data 从@T中选择* 返回 结束

答案 7 :(得分:0)

尽管这个问题很老,但是作为软件开发中的一个新手,我无法停止分享自己学到的知识:D

创建存储过程:

CREAET PROC usp_ValidateUSer
(
    @UserName nVARCHAR(50),
    @Password nVARCHAR(50)
)
AS

BEGIN
    IF EXISTS(SELECT '#' FROM Users WHERE Username=@UserName AND Password=@Password)
    BEGIN
        SELECT u.UserId, u.Username, r.UserRole
        FROM Users u
        INNER JOIN UserRoles r
        ON u.UserRoleId=r.UserRoleId
    END
END

执行存储过程:

(如果要在SQL中测试存储过程的执行情况)

EXEC usp_ValidateUSer @UserName='admin', @Password='admin'

Th输出:

enter image description here

答案 8 :(得分:-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