2009-01-13 12 views
42

यह एक वाक्य रचना सवाल मैं एक दुकान प्रक्रिया या समारोह है कि मैं इस तरह के रूप एक प्रश्न में एम्बेड कर सकते लिखने के लिए कोशिश कर रहा हूँ की अधिक है मैं एक सारणीबद्ध कार्य को परिभाषित करने की कोशिश कर रहा हूं लेकिन मुझे समझ में नहीं आता कि मैं इसे कैसे करना है क्योंकि मैं आखिरकार एंडटेबल पर वापसी करने से पहले डेटा को काम करने के लिए टीएमपी टेबल बना सकता हूं। मेरे कोड के लिए मेरे मार्क अप है:एक समारोह या दुकान प्रक्रिया से एक मेज लौटने TSQL

create function FnGetCompanyIdWithCategories() 
returns table 
as 
return 
(
select * into a #tempTable from stuff 
' 
etc 
' 
select companyid,Company_MarketSector from #tempTables 'the returning table data 
) 

अगर मैं एक समारोह को परिभाषित, मैं इसे कैसे एक मेज के रूप में वापसी करते हैं?

उत्तर

58

आप से अस्थायी टेबल्स उपयोग नहीं कर सकते से एक एसक्यूएल फंक्शन के भीतर। तुम इतनी अनिवार्य रूप से तालिका चर का उपयोग करने की आवश्यकता होगी:

ALTER FUNCTION FnGetCompanyIdWithCategories() 
RETURNS @rtnTable TABLE 
(
    -- columns returned by the function 
    ID UNIQUEIDENTIFIER NOT NULL, 
    Name nvarchar(255) NOT NULL 
) 
AS 
BEGIN 
DECLARE @TempTable table (id uniqueidentifier, name nvarchar(255)....) 

insert into @myTable 
select from your stuff 

--This select returns data 
insert into @rtnTable 
SELECT ID, name FROM @mytable 
return 
END 

संपादित

इस सवाल का टिप्पणी के आधार पर यहाँ मेरी सिफारिश है। आप किसी अन्य क्वेरी में किसी प्रक्रिया या तालिका मूल्यवान फ़ंक्शन के परिणामों में शामिल होना चाहते हैं। मैं आपको दिखाऊंगा कि आप इसे कैसे कर सकते हैं, फिर आप उसे पसंद करते हैं। मैं अपने स्कीमा में से एक से नमूना कोड का उपयोग करने जा रहा हूं, लेकिन आप इसे अनुकूलित करने में सक्षम होना चाहिए। दोनों संग्रहित प्रक्रिया के साथ पहले व्यवहार्य समाधान हैं।

declare @table as table (id int, name nvarchar(50),templateid int,account nvarchar(50)) 

insert into @table 
execute industry_getall 

select * 
from @table 
inner join [user] 
    on account=[user].loginname 

इस मामले में आपको प्रक्रिया के परिणामों को संग्रहीत करने के लिए एक अस्थायी तालिका या तालिका चर घोषित करना होगा। अब तुम ऐसा कैसे करोगे पर नजर डालते हैं अगर आप एक यूडीएफ

select * 
from fn_Industry_GetAll() 
inner join [user] 
    on account=[user].loginname 

उपयोग कर रहे थे कि आप देख सकते यूडीएफ एक बहुत अधिक संक्षिप्त पढ़ने में आसान है, और probally एक छोटा सा बेहतर प्रदर्शन करती है, क्योंकि आप उपयोग नहीं कर रहे हैं द्वितीयक अस्थायी तालिका (प्रदर्शन मेरे भाग पर एक पूर्ण अनुमान है)।

यदि आप कई अन्य स्थानों में अपने कार्य/प्रक्रिया का पुन: उपयोग करने जा रहे हैं, तो मुझे लगता है कि यूडीएफ आपकी सबसे अच्छी पसंद है। एकमात्र पकड़ है कि आपको # टेम्पलेट टेबल का उपयोग करना बंद कर देना होगा और तालिका चर का उपयोग करना होगा। जब तक आप अपनी temp तालिका को अनुक्रमणित नहीं कर रहे हैं, तब तक कोई समस्या नहीं होनी चाहिए, और आप tempDb को कम से कम उपयोग कर रहे हैं क्योंकि तालिका चर मेमोरी में रखा जाता है।

+0

कहने में त्रुटि मिलती है क्योंकि वह ऐसे परिदृश्य का वर्णन कर रहा है जहां एक एसपी यूडीएफ से अधिक उपयुक्त है। वह पूछ रहा है कि किस का उपयोग करना है, और एसपी पर्याप्त है (और सरल और अधिक समेकित और अधिक पोर्टेबल)। – dkretz

+0

मान लीजिए कि वह वास्तव में समारोह में पैरामीटर पास नहीं कर रहा है। – JoshBerke

+0

मैंने सोचा कि स्पोक सबसे अच्छा होगा, साथ ही मैं डेटा की तालिका को वापस करने के लिए temp टेबल का उपयोग कर रहा हूं, लेकिन जब मैं "TheSproc से * चुनें" का प्रयास करता हूं, तो मुझे "अवैध ऑब्जेक्ट नाम" Sproc ' – thiswayup

6

आपको table valued function. के नाम से जाना जाने वाला एक विशेष प्रकार का फ़ंक्शन चाहिए, नीचे कुछ हद तक लंबे हवादार उदाहरण है जो डेटा वेयरहाउस के लिए दिनांक आयाम बनाता है। returns खंड पर ध्यान दें जो तालिका संरचना को परिभाषित करता है। आप टेबल वैरिएबल (@DateHierarchy) में कुछ भी डाल सकते हैं जो आप चाहते हैं, जिसमें अस्थायी तालिका बनाना और सामग्री को कॉपी करना शामिल है।

if object_id ('ods.uf_DateHierarchy') is not null 
    drop function ods.uf_DateHierarchy 
go 

create function ods.uf_DateHierarchy (
     @DateFrom datetime 
     ,@DateTo datetime 
) returns @DateHierarchy table (
     DateKey   datetime 
     ,DisplayDate  varchar (20) 
     ,SemanticDate  datetime 
     ,MonthKey   int  
     ,DisplayMonth  varchar (10) 
     ,FirstDayOfMonth datetime 
     ,QuarterKey  int 
     ,DisplayQuarter varchar (10) 
     ,FirstDayOfQuarter datetime 
     ,YearKey   int 
     ,DisplayYear  varchar (10) 
     ,FirstDayOfYear datetime 
) as begin 
    declare @year   int 
      ,@quarter   int 
      ,@month   int 
      ,@day    int 
      ,@m1ofqtr   int 
      ,@DisplayDate  varchar (20) 
      ,@DisplayQuarter varchar (10) 
      ,@DisplayMonth varchar (10) 
      ,@DisplayYear  varchar (10) 
      ,@today   datetime 
      ,@MonthKey  int 
      ,@QuarterKey  int 
      ,@YearKey   int 
      ,@SemanticDate datetime 
      ,@FirstOfMonth datetime 
      ,@FirstOfQuarter datetime 
      ,@FirstOfYear  datetime 
      ,@MStr   varchar (2) 
      ,@QStr   varchar (2) 
      ,@Ystr   varchar (4) 
      ,@DStr   varchar (2) 
      ,@DateStr   varchar (10) 


    -- === Previous =================================================== 
    -- Special placeholder date of 1/1/1800 used to denote 'previous' 
    -- so that naive date calculations sort and compare in a sensible 
    -- order. 
    -- 
    insert @DateHierarchy (
     DateKey 
     ,DisplayDate 
     ,SemanticDate 
     ,MonthKey 
     ,DisplayMonth 
     ,FirstDayOfMonth 
     ,QuarterKey 
     ,DisplayQuarter 
     ,FirstDayOfQuarter 
     ,YearKey 
     ,DisplayYear 
     ,FirstDayOfYear 
    ) values (
     '1800-01-01' 
     ,'Previous' 
     ,'1800-01-01' 
     ,180001 
     ,'Prev' 
     ,'1800-01-01' 
     ,18001 
     ,'Prev' 
     ,'1800-01-01' 
     ,1800 
     ,'Prev' 
     ,'1800-01-01' 
    ) 

    -- === Calendar Dates ============================================= 
    -- These are generated from the date range specified in the input 
    -- parameters. 
    -- 
    set @today = @Datefrom 
    while @today <= @DateTo begin 

     set @year = datepart (yyyy, @today) 
     set @month = datepart (mm, @today) 
     set @day = datepart (dd, @today) 
     set @quarter = case when @month in (1,2,3) then 1 
          when @month in (4,5,6) then 2 
          when @month in (7,8,9) then 3 
          when @month in (10,11,12) then 4 
         end 
     set @m1ofqtr = @quarter * 3 - 2 

     set @DisplayDate = left (convert (varchar, @today, 113), 11) 
     set @SemanticDate = @today 
     set @MonthKey = @year * 100 + @month 
     set @DisplayMonth = substring (convert (varchar, @today, 113), 4, 8) 
     set @Mstr = right ('0' + convert (varchar, @month), 2) 
     set @Dstr = right ('0' + convert (varchar, @day), 2) 
     set @Ystr = convert (varchar, @year) 
     set @DateStr = @Ystr + '-' + @Mstr + '-01' 
     set @FirstOfMonth = convert (datetime, @DateStr, 120) 
     set @QuarterKey = @year * 10 + @quarter 
     set @DisplayQuarter = 'Q' + convert (varchar, @quarter) + ' ' + 
            convert (varchar, @year) 
     set @QStr = right ('0' + convert (varchar, @m1ofqtr), 2) 
     set @DateStr = @Ystr + '-' + @Qstr + '-01' 
     set @FirstOfQuarter = convert (datetime, @DateStr, 120) 
     set @YearKey = @year 
     set @DisplayYear = convert (varchar, @year) 
     set @DateStr = @Ystr + '-01-01' 
     set @FirstOfYear = convert (datetime, @DateStr) 


     insert @DateHierarchy (
      DateKey 
      ,DisplayDate 
      ,SemanticDate 
      ,MonthKey 
      ,DisplayMonth 
      ,FirstDayOfMonth 
      ,QuarterKey 
      ,DisplayQuarter 
      ,FirstDayOfQuarter 
      ,YearKey 
      ,DisplayYear 
      ,FirstDayOfYear 
     ) values (
      @today 
      ,@DisplayDate 
      ,@SemanticDate 
      ,@Monthkey 
      ,@DisplayMonth 
      ,@FirstOfMonth 
      ,@QuarterKey 
      ,@DisplayQuarter 
      ,@FirstOfQuarter 
      ,@YearKey 
      ,@DisplayYear 
      ,@FirstOfYear 
     ) 

     set @today = dateadd (dd, 1, @today) 
    end 

    -- === Specials =================================================== 
    -- 'Ongoing', 'Error' and 'Not Recorded' set two years apart to 
    -- avoid accidental collisions on 'Next Year' calculations. 
    -- 
    insert @DateHierarchy (
     DateKey 
     ,DisplayDate 
     ,SemanticDate 
     ,MonthKey 
     ,DisplayMonth 
     ,FirstDayOfMonth 
     ,QuarterKey 
     ,DisplayQuarter 
     ,FirstDayOfQuarter 
     ,YearKey 
     ,DisplayYear 
     ,FirstDayOfYear 
    ) values (
     '9000-01-01' 
     ,'Ongoing' 
     ,'9000-01-01' 
     ,900001 
     ,'Ong.' 
     ,'9000-01-01' 
     ,90001 
     ,'Ong.' 
     ,'9000-01-01' 
     ,9000 
     ,'Ong.' 
     ,'9000-01-01' 
    ) 

    insert @DateHierarchy (
     DateKey 
     ,DisplayDate 
     ,SemanticDate 
     ,MonthKey 
     ,DisplayMonth 
     ,FirstDayOfMonth 
     ,QuarterKey 
     ,DisplayQuarter 
     ,FirstDayOfQuarter 
     ,YearKey 
     ,DisplayYear 
     ,FirstDayOfYear 
    ) values (
     '9100-01-01' 
     ,'Error' 
     ,null 
     ,910001 
     ,'Error' 
     ,null 
     ,91001 
     ,'Error' 
     ,null 
     ,9100 
     ,'Err' 
     ,null 
    ) 

    insert @DateHierarchy (
     DateKey 
     ,DisplayDate 
     ,SemanticDate 
     ,MonthKey 
     ,DisplayMonth 
     ,FirstDayOfMonth 
     ,QuarterKey 
     ,DisplayQuarter 
     ,FirstDayOfQuarter 
     ,YearKey 
     ,DisplayYear 
     ,FirstDayOfYear 
    ) values (
     '9200-01-01' 
     ,'Not Recorded' 
     ,null 
     ,920001 
     ,'N/R' 
     ,null 
     ,92001 
     ,'N/R' 
     ,null 
     ,9200 
     ,'N/R' 
     ,null 
    ) 

    return 
end 

go 
+0

आपको क्यों लगता है कि उसे संग्रहीत प्रक्रिया के बजाय इसकी आवश्यकता है? – dkretz

+0

आपको क्यों लगता है कि उसे संग्रहीत प्रक्रिया के बजाय इसकी आवश्यकता है? क्या आप निष्कर्ष निकाल सकते हैं कि बिना किसी प्रश्न के? – dkretz

+1

आप वास्तव में किसी संग्रहित प्रक्रिया को किसी क्वेरी में एम्बेड नहीं कर सकते हैं - सबसे अच्छा आप इसे कर सकते हैं एक रिकॉर्ड सेट से तालिका में डालने के लिए। साथ ही, वह विशेष रूप से टेबल मूल्यवान फ़ंक्शन को लिखने के तरीके के बारे में सहायता मांगने के लिए कहता है। – ConcernedOfTunbridgeWells

9

एक टेम्पलेट

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  <Author,,Name> 
-- Create date: <Create Date,,> 
-- Description: <Description,,> 
-- ============================================= 
CREATE FUNCTION <Table_Function_Name, sysname, FunctionName> 
(
    -- Add the parameters for the function here 
    <@param1, sysname, @p1> <data_type_for_param1, , int>, 
    <@param2, sysname, @p2> <data_type_for_param2, , char> 
) 
RETURNS 
<@Table_Variable_Name, sysname, @Table_Var> TABLE 
(
    -- Add the column definitions for the TABLE variable here 
    <Column_1, sysname, c1> <Data_Type_For_Column1, , int>, 
    <Column_2, sysname, c2> <Data_Type_For_Column2, , int> 
) 
AS 
BEGIN 
    -- Fill the table variable with the rows for your result set 

    RETURN 
END 
GO 

कि आपके समारोह परिभाषित करेगा के रूप में इस का प्रयोग करें। तो फिर तुम किसी भी अन्य तालिका के रूप में यह प्रयोग करेंगे:

Select * from MyFunction(Param1, Param2, etc.) 
2

आप जहाँ तक मैं बता सकता है की जरूरत नहीं है (उपयोग नहीं करना चाहिए) एक समारोह। संग्रहीत प्रक्रिया किसी भी SELECT कथन से टैब्यूलर डेटा लौटाएगी जिसमें आप टैब्यूलर डेटा लौटाते हैं।

एक संग्रहित प्रो रिटर्न बयान का उपयोग नहीं करती है।

बनाएं प्रक्रिया नाम के रूप में

चयन सामान जांच # temptbl1

.......

कॉलम

#temptbln
+3

यदि मैं "MySproc से * का चयन करता हूं" तो मुझे "अवैध ऑब्जेक्ट नाम 'theproc' ' – thiswayup

संबंधित मुद्दे