我有一个存储过程,它接受两个参数。我可以在Server Management Studio中成功执行它。它向我展示了我期望的结果。但是它也会返回一个返回值。
已添加此行,
SELECT 'Return Value' = @return_value
我希望存储过程返回它在结果中显示的表而不是返回值,因为我从MATLAB调用此存储过程,并且它返回的全部为true或false。
我是否需要在我的存储过程中指定它应该返回什么?如果是这样,我如何指定一个包含4列的表(varchar(10),float,float,float)?
答案 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输出:
答案 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