2014-04-09 18 views
17

Tôi có một thủ tục lưu sẵn có hai tham số. Tôi có thể thực thi thành công trong Server Management Studio. Nó cho tôi thấy kết quả như tôi mong đợi. Tuy nhiên nó cũng trả về một giá trị trả lại.Thủ tục lưu trữ SQL Server trả về một bảng

Nó đã được thêm vào dòng này,

SELECT 'Return Value' = @return_value 

Tôi muốn các thủ tục lưu trữ để trả lại bảng đó cho thấy tôi trong các kết quả không phải là giá trị trả về như tôi gọi thủ tục lưu trữ này từ MATLAB và tất cả nó sẽ trả về là đúng hay sai.

Tôi có cần phải chỉ định trong quy trình lưu trữ của mình những gì cần trả lại không? Nếu vậy làm thế nào để tôi chỉ định một bảng gồm 4 cột (varchar (10), float, float, float)?

Trả lời

37

Quy trình không thể trả lại bảng như vậy. Tuy nhiên, bạn có thể chọn từ bảng trong quy trình và chuyển nó vào bảng (hoặc biến bảng) như sau:

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

Tôi khuyên bạn nên xem giải pháp [** this **] (http://stackoverflow.com/questions/5604927/how-to-return-a-table-from-stored-procedure). Người ta sẽ trực giác nghĩ rằng nó sẽ không hoạt động, nhưng nó làm, làm cho nó là cách đơn giản nhất để làm điều này. – Veverke

-1

Đây là ví dụ về SP trả về bảng và trả về giá trị. Tôi không biết nếu bạn cần trả lại "Giá trị trả lại" và tôi không có ý tưởng về MATLAB và những gì nó đòi hỏi.

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

Bạn có thể sử dụng một tham số ra thay vì giá trị trả về nếu bạn muốn cả một tập hợp kết quả và giá trị trả về

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

Giá trị Status được trả về bởi một Stored Procedure chỉ có thể là một INT loại dữ liệu. Bạn không thể trả về các kiểu dữ liệu khác trong câu lệnh RETURN.

Từ Lesson 2: Designing Stored Procedures:

Mỗi thủ tục lưu trữ có thể trả về một số nguyên giá trị được gọi là giá trị tình trạng thực hiện hoặc trả lại mã.

Nếu bạn vẫn muốn một bảng được trả về từ SP, bạn sẽ phải làm việc bộ bản ghi được trả về từ một SELECT trong SP hoặc gắn vào biến OUTPUT chuyển một kiểu dữ liệu XML.

HTH,

John

4

xem xét việc tạo ra một chức năng mà có thể trả về một bảng và được sử dụng trong một truy vấn.

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

Sự khác biệt chính giữa một hàm và thủ tục là một chức năng làm cho không có thay đổi bất kỳ bảng. Nó chỉ trả về một giá trị.

Trong ví dụ này, tôi tạo truy vấn để cung cấp cho tôi tổng số của tất cả các cột trong bảng đã cho không rỗng hoặc trống.

Có thể có nhiều cách để làm sạch điều này. Nhưng nó minh họa một chức năng tốt.

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 

Sau đó, thực hiện các chức năng với

SELECT * FROM usp_listFields('Employees') 

sản xuất một số hàng như:

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

Hai lỗi trong tập lệnh của bạn: -Trong quy trình được lưu trữ, UNION cuối cùng phải được bỏ qua. Vì vậy, việc thực hiện đoạn mã thứ ba đưa ra một lỗi, có thể được sửa bằng cách loại bỏ UNION cuối cùng. - Trong đoạn mã thứ hai khi bạn gọi usp_listFields, bạn PHẢI cung cấp cả lược đồ và bảng đối số. – Jan

+0

Nếu bạn muốn tìm hiểu thêm về trả về giá trị, đặt biến đầu ra và trả lại dữ liệu phức tạp hơn như bảng hoàn chỉnh, hãy xem các hướng dẫn tuyệt vời này tại https://www.youtube.com/playlist?list=PLNIs-AWhQzcleQWADpUgriRxebMkMmi4H – Jan

2

tôi đã có một tình huống tương tự và giải quyết bằng cách sử dụng một bảng tạm thời bên trong thủ tục, với cùng các trường được trả lại theo Quy trình được lưu trữ ban đầu:

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

chèn vào @ T exec [chủ] .dbo.sp_executesql @q lấy tiếp theo từ @data vào @ c @ b cuối @data gần deallocate @data select * from @ T return end

2

Tôi làm điều này thường xuyên bằng cách sử dụng các loại bảng để đảm bảo tính nhất quán hơn và đơn giản hóa mã. Bạn không thể trả về "bảng" một cách kỹ thuật, nhưng bạn có thể trả về một tập hợp kết quả và sử dụng cú pháp INSERT INTO .. EXEC ..., bạn có thể gọi rõ ràng một PROC và lưu kết quả vào một loại bảng. Trong ví dụ sau, tôi thực sự chuyển một bảng vào một PROC cùng với một tham số khác tôi cần thêm logic, sau đó tôi thực sự "trả về một bảng" và sau đó có thể làm việc với nó như một biến bảng.

/****** 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 
Các vấn đề liên quan