sql একটি অস্থায়ী টেবিলে একটি সংরক্ষিত পদ্ধতি ফলাফল সন্নিবেশ করান




sql-server sql-server-2005 (20)

আমি কিভাবে একটি SELECT * INTO [temp table] FROM [stored procedure] ? না FROM [Table] এবং [temp table] সংজ্ঞায়িত ছাড়া?

BusinessLine থেকে tmpBusLine সমস্ত তথ্য জরিমানা কাজ করে।

select *
into tmpBusLine
from BusinessLine

আমি একই চেষ্টা করছি, কিন্তু তথ্য ফেরত একটি stored procedure ব্যবহার করে, বেশ একই।

select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'

আউটপুট বার্তা:

বার্তা 156, স্তর 15, রাজ্য 1, লাইন 2 শব্দ 'exec' এর কাছাকাছি ভুল সিনট্যাক্স।

আমি আউটপুট সংরক্ষণ পদ্ধতি হিসাবে একই কাঠামোর সাথে একটি অস্থায়ী টেবিল তৈরি করার বেশ কয়েকটি উদাহরণ পড়ি, যা জরিমানা করে তবে কোন কলাম সরবরাহ করা ভাল হবে।


একটি সঞ্চিত পদ্ধতির প্রথম রেকর্ড সেটটি একটি অস্থায়ী টেবিলে সন্নিবেশ করার জন্য আপনাকে নিম্নলিখিতগুলি জানতে হবে:

  1. সঞ্চিত পদ্ধতির প্রথম সারি সেটটি একটি অস্থায়ী টেবিলের মধ্যে সন্নিবেশ করা যেতে পারে
  2. সঞ্চিত পদ্ধতিটি গতিশীল টি-এসকিউএল বিবৃতিটি চালানো উচিত নয় ( sp_executesql )
  3. আপনি প্রথমে অস্থায়ী টেবিলের গঠন সংজ্ঞায়িত করতে হবে

উপরে সীমাবদ্ধতা হিসাবে দেখা যেতে পারে, কিন্তু IMHO এটি পুরোপুরি ইন্দ্রিয়গ্রাহী করে তোলে - যদি আপনি sp_executesql ব্যবহার করেন sp_executesql আপনি একবার দুটি কলাম এবং একবার দশটি ফেরত sp_executesql পারেন এবং যদি আপনার একাধিক ফলাফল সেট থাকে তবে আপনি sp_executesql সন্নিবেশ করতে পারবেন না - আপনি সন্নিবেশ করতে পারেন একটি টি-এসকিউএল বিবৃতিতে দুটি টেবিলে সর্বাধিক ( OUTPUT ধারা এবং কোন ট্রিগার ব্যবহার করে)।

সুতরাং, ইস্যুটি সম্পাদন করার আগে অস্থায়ী টেবিলের কাঠামো কীভাবে সংজ্ঞায়িত করতে হবে তা হল সমস্যা EXEC ... INTO ... বিবৃতি।

OBJECT_ID সাথে প্রথম কাজটি দ্বিতীয় এবং তৃতীয়টি অ্যাড-হক প্রশ্নের সাথেও কাজ করে। আমি স্প্যামের পরিবর্তে DMV ব্যবহার করতে পছন্দ করি কারণ আপনি CROSS APPLY প্রয়োগ করতে পারেন এবং একই সময়ে একাধিক পদ্ধতির জন্য অস্থায়ী টেবিল সংজ্ঞাগুলি তৈরি করতে পারেন।

SELECT p.name, r.* 
FROM sys.procedures AS p
CROSS APPLY sys.dm_exec_describe_first_result_set_for_object(p.object_id, 0) AS r;

এছাড়াও, system_type_name ক্ষেত্রে মনোযোগ দিন কারণ এটি খুব দরকারী হতে পারে। এটি কলাম সম্পূর্ণ সংজ্ঞা সঞ্চয় করে। উদাহরণ স্বরূপ:

smalldatetime
nvarchar(max)
uniqueidentifier
nvarchar(1000)
real
smalldatetime
decimal(18,2)

এবং আপনি টেবিল সংজ্ঞা তৈরি করতে বেশিরভাগ ক্ষেত্রে সরাসরি এটি ব্যবহার করতে পারেন।

সুতরাং, আমি বেশিরভাগ ক্ষেত্রে মনে করি (যদি সংরক্ষিত পদ্ধতিটি নির্দিষ্ট মানদণ্ডের সাথে মিলিত হয়) আপনি সহজেই এই সমস্যাগুলি সমাধান করার জন্য গতিশীল বিবৃতিগুলি তৈরি করতে পারেন (অস্থায়ী টেবিল তৈরি করুন, এতে সংরক্ষিত প্রক্রিয়া ফলাফলটি ঢোকান, তথ্য দিয়ে আপনার যা প্রয়োজন তা সন্নিবেশ করান) ।

উল্লেখ্য, উপরের বস্তুগুলি প্রথম কোনও cases প্রথম ফলাফল সেট ডেটা সংজ্ঞায়িত করতে ব্যর্থ হয়েছে যেমন ডাইনামিক টি-এসকিউএল বিবৃতিগুলি কার্যকর করা হয় বা অস্থায়ী টেবিলগুলি সঞ্চিত পদ্ধতিতে ব্যবহৃত হয়।


SQL সার্ভার 2005 এ আপনি INSERT INTO ... EXEC ব্যবহার করতে পারেন INSERT INTO ... EXEC একটি সারণিতে একটি সংরক্ষিত পদ্ধতির ফলাফল সন্নিবেশ করতে। এমএসডিএন এর INSERT ডকুমেন্টেশন থেকে (এসকিউএল সার্ভার 2000 এর জন্য, আসলে):

--INSERT...EXECUTE procedure example
INSERT author_sales EXECUTE get_author_sales

যদি ক্যোয়ারিতে প্যারামিটার থাকে না তবে OpenQueryঅন্যটি ব্যবহার করুন OpenRowset

বেসিক জিনিস সঞ্চিত পদ্ধতি অনুযায়ী স্কিমা তৈরি করা এবং যে টেবিলের মধ্যে সন্নিবেশ করা হবে। উদাহরণ:

DECLARE @abc TABLE(
                  RequisitionTypeSourceTypeID INT
                , RequisitionTypeID INT
                , RequisitionSourcingTypeID INT
                , AutoDistOverride INT
                , AllowManagerToWithdrawDistributedReq INT
                , ResumeRequired INT
                , WarnSupplierOnDNRReqSubmission  INT
                , MSPApprovalReqd INT
                , EnableMSPSupplierCounterOffer INT
                , RequireVendorToAcceptOffer INT
                , UseCertification INT
                , UseCompetency INT
                , RequireRequisitionTemplate INT
                , CreatedByID INT
                , CreatedDate DATE
                , ModifiedByID INT
                , ModifiedDate DATE
                , UseCandidateScheduledHours INT
                , WeekEndingDayOfWeekID INT
                , AllowAutoEnroll INT
                )
INSERT INTO @abc
EXEC [dbo].[usp_MySp] 726,3
SELECT * FROM @abc

আপনার সংরক্ষিত প্রসেসের ফলাফল টেবিলটি "তৈরি টেবিল" বিবৃতিটি হাত দ্বারা অত্যন্ত জটিল হলে এবং আপনি OPENQUERY বা OPENROWSET ব্যবহার করতে পারবেন না, আপনি আপনার জন্য কলাম এবং ডেটা প্রকারের তালিকা তৈরি করতে sp_help ব্যবহার করতে পারেন। একবার আপনার কলামগুলির তালিকা আছে, এটি আপনার প্রয়োজন অনুসারে এটি ফর্ম্যাট করার ব্যাপার।

ধাপ 1: আউটপুট অনুসন্ধানের জন্য "# টিমপিতে" যোগ করুন (উদাহরণস্বরূপ "# [...] থেকে # টিমপ মধ্যে [...]" নির্বাচন করুন)।

সবচেয়ে সহজ উপায় সরাসরি proc মধ্যে আউটপুট প্রশ্নের সম্পাদনা করতে হয়। যদি আপনি সংরক্ষণ করা প্রসেসটি পরিবর্তন করতে না পারেন তবে আপনি সামগ্রীগুলিকে একটি নতুন ক্যোয়ারী উইন্ডোতে অনুলিপি করতে এবং সেখানে অনুসন্ধানের প্রশ্নটি সংশোধন করতে পারেন।

পদক্ষেপ 2: টেম্প টেবিলে sp_help চালান। (যেমন "exec tempdb..sp_help #temp")

টেম্প টেবিল তৈরি করার পরে, কলামের তালিকা এবং ভার্চার ক্ষেত্রের আকার সহ ডেটা প্রকারের তালিকা পেতে টেম্প টেবিলের sp_help চালান।

ধাপ 3: একটি ডাটা টেবিল বিবৃতিতে ডাটা কলাম এবং প্রকারগুলি অনুলিপি করুন

আমার একটি এক্সেল শীট আছে যা আমি sp_help এর আউটপুটটিকে "তৈরি টেবিল" বিবৃতিতে বিন্যাস করতে ব্যবহার করি। আপনি যে অভিনব কিছু প্রয়োজন হয় না, শুধু আপনার এসকিউএল এডিটর মধ্যে কপি এবং পেস্ট। "টেবিল #x [...]" বা "x টেবিল ঘোষণা করুন [...]" বিবৃতিটি তৈরি করতে কলামের নাম, মাপ এবং প্রকারগুলি ব্যবহার করুন যা আপনি সংরক্ষিত পদ্ধতির ফলাফলগুলি INSERT তে ব্যবহার করতে পারেন।

পদক্ষেপ 4: নতুন তৈরি টেবিলে প্রবেশ করান

এখন আপনার কাছে একটি প্রশ্ন থাকবে যা এই থ্রেডে বর্ণিত অন্যান্য সমাধানগুলির মতো।

DECLARE @t TABLE 
(
   --these columns were copied from sp_help
   COL1 INT,
   COL2 INT   
)

INSERT INTO @t 
Exec spMyProc 

এই কৌশলটি একটি টেম্প টেবিল ( #temp ) কে একটি টেবিল পরিবর্তনশীল ( @temp #temp ) রূপান্তর করতেও ব্যবহার করা যেতে পারে। এটি কেবল create table বিবৃতিটি লেখার চেয়ে আরও বেশি পদক্ষেপ হতে পারে, এটি ম্যানুয়াল ত্রুটিগুলি যেমন টাইপস এবং ডেটা টাইপ মিষমাচগুলি বড় প্রসেসগুলিতে বাধা দেয়। একটি টাইপ ডিবাগিং প্রথম স্থানে প্রশ্নটি লেখার চাইতে বেশি সময় নিতে পারে।


কোড

CREATE TABLE #T1
(
    col1 INT NOT NULL,
    col2 NCHAR(50) NOT NULL,
    col3 TEXT NOT NULL,
    col4 DATETIME NULL,
    col5 NCHAR(50) NULL,
    col6 CHAR(2) NULL,
    col6 NCHAR(100) NULL,
    col7 INT NULL,
    col8 NCHAR(50) NULL,
    col9 DATETIME NULL,
    col10 DATETIME NULL
)

DECLARE @Para1 int
DECLARE @Para2 varchar(32)
DECLARE @Para3 varchar(100)
DECLARE @Para4 varchar(15)
DECLARE @Para5 varchar (12)
DECLARE @Para6 varchar(1)
DECLARE @Para7 varchar(1)


SET @Para1 = 1025
SET @Para2 = N'6as54fsd56f46sd4f65sd'
SET @Para3 = N'XXXX\UserName'
SET @Para4 = N'127.0.0.1'
SET @Para5 = N'XXXXXXX'
SET @Para6 = N'X'
SET @Para7 = N'X'

INSERT INTO #T1
(
    col1,
    col2,
    col3,
    col4,
    col5,
    col6,
    col6,
    col7,
    col8,
    col9,
    col10,
)
EXEC [dbo].[usp_ProcedureName] @Para1, @Para2, @Para3, @Para4, @Para5, @Para6, @Para6

আশা করি এটা কাজে লাগবে. উপযুক্ত হিসাবে যোগ্যতা অর্জন করুন।


  1. আমি নিম্নলিখিত স্কিমা এবং তথ্য সঙ্গে একটি টেবিল তৈরি করছি।
  2. একটি সংরক্ষিত পদ্ধতি তৈরি করুন।
  3. এখন আমি জানি আমার পদ্ধতির ফলাফল কি, তাই আমি নিম্নলিখিত প্রশ্নের সাথে কাজ করছি।

    CREATE TABLE [dbo].[tblTestingTree](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [ParentId] [int] NULL,
        [IsLeft] [bit] NULL,
        [IsRight] [bit] NULL,
    CONSTRAINT [PK_tblTestingTree] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    SET IDENTITY_INSERT [dbo].[tblTestingTree] ON
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (1, NULL, NULL, NULL)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (2, 1, 1, NULL)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (3, 1, NULL, 1)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (4, 2, 1, NULL)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (5, 2, NULL, 1)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (6, 3, 1, NULL)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (7, 3, NULL, 1)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (8, 4, 1, NULL)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (9, 4, NULL, 1)
    INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (10, 5, 1, NULL)
    
    SET IDENTITY_INSERT [dbo].[tblTestingTree] OFF

    মূল্য (10, 5, 1, নুল) সেট IDENTITY_INSERT [dbo]। [TblTestingTree] চালু

    create procedure GetDate
    as
    begin
        select Id,ParentId from tblTestingTree
    end
    
    create table tbltemp
    (
        id int,
        ParentId int
    )
    insert into tbltemp
    exec GetDate
    
    select * from tbltemp;

এটি আপনার প্রশ্নের সামান্য সংশোধিত সংস্করণের একটি উত্তর। আপনি ব্যবহারকারী-সংজ্ঞায়িত ফাংশনের জন্য একটি সংরক্ষিত পদ্ধতির ব্যবহার পরিত্যাগ করতে পারেন, আপনি একটি ইনলাইন সারণী-মূল্যবান ব্যবহারকারী-সংজ্ঞায়িত ফাংশন ব্যবহার করতে পারেন। এটি মূলত একটি সংরক্ষিত পদ্ধতি (পরামিতি গ্রহণ করবে) যা একটি ফলাফল হিসাবে একটি টেবিল প্রদান করে; এবং তাই একটি INTO বিবৃতি সঙ্গে চমত্কারভাবে স্থাপন করা হবে।

এখানে এটি এবং অন্যান্য ব্যবহারকারী-সংজ্ঞায়িত ফাংশন উপর একটি ভাল দ্রুত নিবন্ধ । যদি আপনার এখনও একটি সংরক্ষিত পদ্ধতির জন্য ড্রাইভিং প্রয়োজন থাকে, আপনি ইনলাইন সারণী-মূল্যবান ব্যবহারকারী-সংজ্ঞায়িত ফাংশনটি একটি সংরক্ষিত পদ্ধতির সাথে মোড়ানো করতে পারেন। সঞ্চিত পদ্ধতিটি কেবলমাত্র প্যারামিটারগুলি পাস করে যখন এটি ইনলাইন সারণির থেকে * নির্বাচন করে * মূল্যবান ব্যবহারকারী-সংজ্ঞায়িত ফাংশন থেকে।

উদাহরণস্বরূপ, উদাহরণস্বরূপ, আপনার একটি নির্দিষ্ট অঞ্চলের গ্রাহকদের তালিকা পেতে একটি ইনলাইন টেবিল-মূল্যবান ব্যবহারকারী-সংজ্ঞায়িত ফাংশন থাকবে:

CREATE FUNCTION CustomersByRegion 
(  
    @RegionID int  
)
RETURNS TABLE 
AS
RETURN 
  SELECT *
  FROM customers
  WHERE RegionID = @RegionID
GO

তারপরে আপনার ফলাফলগুলি কী পেতে পারে তার জন্য আপনি এই ফাংশনটি কল করতে পারেন:

SELECT * FROM CustomersbyRegion(1)

অথবা একটি নির্বাচন করতে:

SELECT * INTO CustList FROM CustomersbyRegion(1)

আপনি এখনও একটি সংরক্ষিত পদ্ধতি প্রয়োজন হলে, ফাংশন মোড়ানো যেমন:

CREATE PROCEDURE uspCustomersByRegion 
(  
    @regionID int  
)
AS
BEGIN
     SELECT * FROM CustomersbyRegion(@regionID);
END
GO

আমি পছন্দসই ফলাফল প্রাপ্ত এই সবচেয়ে হ্যাক-কম 'পদ্ধতি মনে হয়। এটি বিদ্যমান বৈশিষ্ট্যগুলি ব্যবহার করে কারণ এটি অতিরিক্ত জটিলতার সাথে ব্যবহার করা হয়েছে। সঞ্চিত পদ্ধতিতে ইনলাইন টেবিল-মূল্যবান ব্যবহারকারী-সংজ্ঞায়িত ফাংশন নিছক করে, আপনার দুটি উপায়ে কার্যকারিতা অ্যাক্সেস আছে। প্লাস! আপনার প্রকৃত এসকিউএল কোডের জন্য রক্ষণাবেক্ষণের মাত্র একটি পয়েন্ট রয়েছে।

OPENROWSET ব্যবহারের পরামর্শ দেওয়া হয়েছে, তবে এটি OPENROWSET ফাংশনটি কীভাবে ব্যবহার করা হয়েছিল (অনলাইন বই থেকে):

একটি OLE ডিবি তথ্য উৎস থেকে দূরবর্তী ডেটা অ্যাক্সেস করতে প্রয়োজনীয় সমস্ত সংযোগ তথ্য অন্তর্ভুক্ত। এই পদ্ধতিটি একটি লিঙ্কযুক্ত সার্ভারে টেবিলগুলি অ্যাক্সেস করার বিকল্প এবং এটি এক-বার, OLE DB ব্যবহার করে দূরবর্তী ডেটা সংযোগ করার এবং অ্যাক্সেস করার বিজ্ঞাপন পদ্ধতি। OLE ডিবি তথ্য উত্সগুলির আরও ঘন ঘন রেফারেন্সের জন্য, পরিবর্তে লিঙ্ক সার্ভারগুলি ব্যবহার করুন।

OPENROWSET ব্যবহার করে কাজটি সম্পন্ন হবে, তবে এটি স্থানীয় সংযোগগুলি এবং মার্শালিং ডেটা খোলার জন্য কিছু অতিরিক্ত ওভারহেড লাগবে। এটি সমস্ত ক্ষেত্রে একটি বিকল্পও হতে পারে না কারণ এটিতে এমন একটি বৈধ হ'ল ক্যোয়ার অনুমতির প্রয়োজন যা নিরাপত্তা ঝুঁকি তৈরি করে এবং তাই এটি পছন্দসই নাও হতে পারে। এছাড়াও, OPENROWSET পদ্ধতির একাধিক ফলাফল সেট ফেরত সংরক্ষিত স্টোরেজ পদ্ধতি ব্যবহার নিষিদ্ধ করা হবে। একাধিক ইনলাইন টেবিল মোড়ানো-মান একক সংরক্ষিত পদ্ধতিতে ব্যবহারকারী-সংজ্ঞায়িত ফাংশন এটি অর্জন করতে পারে।


আমি সংরক্ষিত পদ্ধতিতে অ্যারে / ডেটাবেবেলগুলি পাস করেছি যা আপনাকে আপনার সমস্যা সমাধানে কীভাবে যেতে পারে সে সম্পর্কে অন্য ধারণা দিতে পারে।

লিঙ্কটি সংরক্ষিত পদ্ধতিতে পাস করার জন্য একটি চিত্র টাইপ প্যারামিটার ব্যবহার করার পরামর্শ দেয় । তারপরে সঞ্চিত পদ্ধতিতে, চিত্রটিকে মূল ডেটা সহ একটি টেবিল পরিবর্তনশীল রূপে রূপান্তরিত করা হয়।

হয়তো একটি অস্থায়ী টেবিল সঙ্গে ব্যবহার করা যেতে পারে একটি উপায় আছে।


EXEC sp_serveroption 'YOURSERVERNAME', 'DATA ACCESS', TRUE

SELECT  *
INTO    #tmpTable
FROM    OPENQUERY(YOURSERVERNAME, 'EXEC db.schema.sproc 1')

declare @temp table
(
    name varchar(255),
    field varchar(255),
    filename varchar(255),
    filegroup varchar(255),
    size varchar(255),
    maxsize varchar(255),
    growth varchar(255),
    usage varchar(255)
);
INSERT @temp  Exec sp_helpfile;
select * from @temp;

আপনি এই জন্য OPENROWSET ব্যবহার করতে পারেন। একটি চেহারা আছে। এড-হক বিতরিত ক্যোয়ারী সক্ষম করার জন্য আমি স্পাইফিকচার কোডটিও ইতিমধ্যে অন্তর্ভুক্ত করেছি, যদি এটি ইতিমধ্যে সক্ষম না হয়।

CREATE PROC getBusinessLineHistory
AS
BEGIN
    SELECT * FROM sys.databases
END
GO

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

SELECT * INTO #MyTempTable FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
     'EXEC getBusinessLineHistory')

SELECT * FROM #MyTempTable

আচ্ছা, আপনাকে একটি টেম্প টেবিল তৈরি করতে হবে, তবে এটি সঠিক স্কিমা থাকতে হবে না .... আমি একটি সংরক্ষিত পদ্ধতি তৈরি করেছি যা একটি বিদ্যমান টেম্প টেবিল সংশোধন করে যাতে সঠিক ডেটা সহ প্রয়োজনীয় কলাম থাকে টাইপ এবং অর্ডার (সব বিদ্যমান কলাম ড্রপ, নতুন কলাম যোগ):

GO
create procedure #TempTableForSP(@tableId int, @procedureId int)  
as   
begin  
    declare @tableName varchar(max) =  (select name  
                                        from tempdb.sys.tables 
                                        where object_id = @tableId
                                        );    
    declare @tsql nvarchar(max);    
    declare @tempId nvarchar(max) = newid();      
    set @tsql = '    
    declare @drop nvarchar(max) = (select  ''alter table tempdb.dbo.' + @tableName 
            +  ' drop column ''  + quotename(c.name) + '';''+ char(10)  
                                   from tempdb.sys.columns c   
                                   where c.object_id =  ' + 
                                         cast(@tableId as varchar(max)) + '  
                                   for xml path('''')  
                                  )    
    alter table tempdb.dbo.' + @tableName + ' add ' + QUOTENAME(@tempId) + ' int;
    exec sp_executeSQL @drop;    
    declare @add nvarchar(max) = (    
                                select ''alter table ' + @tableName 
                                      + ' add '' + name 
                                      + '' '' + system_type_name 
                           + case when d.is_nullable=1 then '' null '' else '''' end 
                                      + char(10)   
                              from sys.dm_exec_describe_first_result_set_for_object(' 
                               + cast(@procedureId as varchar(max)) + ', 0) d  
                                order by column_ordinal  
                                for xml path(''''))    

    execute sp_executeSQL  @add;    
    alter table '  + @tableName + ' drop column ' + quotename(@tempId) + '  ';      
    execute sp_executeSQL @tsql;  
end         
GO

create table #exampleTable (pk int);

declare @tableId int = object_Id('tempdb..#exampleTable')
declare @procedureId int = object_id('examplestoredProcedure')

exec #TempTableForSP @tableId, @procedureId;

insert into #exampleTable
exec examplestoredProcedure

মনে রাখবেন এটি sys.dm_exec_describe_first_result_set_for_object সংরক্ষণকৃত পদ্ধতির ফলাফল নির্ধারণ করতে পারে না (উদাহরণস্বরূপ এটি একটি টেম্প টেবিল ব্যবহার করে)।


এসকিউএল সার্ভার ২014+ এ এটি করা যেতে পারে তবে প্রদত্ত SP শুধুমাত্র একটি টেবিল প্রদান করে। যদি কেউ একাধিক সারণির জন্য এটি করার একটি উপায় খুঁজে পায় তবে আমি এটি সম্পর্কে জানতে চাই।

DECLARE @storeProcname NVARCHAR(MAX) = ''

SET @storeProcname = 'myStoredProc'

DECLARE @strSQL AS VARCHAR(MAX) = 'CREATE TABLE myTableName '

SELECT @strSQL = @strSQL+STUFF((
SELECT ',' +name+' ' + system_type_name 
FROM sys.dm_exec_describe_first_result_set_for_object (OBJECT_ID(@storeProcname),0)
FOR XML PATH('')
),1,1,'(') + ')'

EXEC (@strSQL)

INSERT INTO myTableName
EXEC ('myStoredProc @param1=1, @param2=2')

SELECT * FROM myTableName

DROP TABLE myTableName

এটি সিস্টেম টেবিল থেকে প্রত্যাবর্তিত টেবিলের সংজ্ঞাটিকে টান করে এবং আপনার জন্য টেম্প টেবিল তৈরি করতে এটি ব্যবহার করে। আপনি আগে বর্ণিত হিসাবে এসপি থেকে এটি ভরাট করতে পারেন।

এছাড়াও ডায়নামিক এসকিউএল সঙ্গে কাজ যে এই রূপ আছে।


যখন সংরক্ষিত পদ্ধতিটি অনেকগুলি কলাম প্রদান করে এবং আপনি ফলাফলটি ধরে রাখার জন্য একটি অস্থায়ী টেবিল "ম্যানুয়ালি" তৈরি করতে চান না, তখন আমি সংরক্ষিত পদ্ধতিতে যান এবং "ইন" ক্লোজ যোগ করার সবচেয়ে সহজ উপায় খুঁজে পাই শেষ নির্বাচন বিবৃতি এবং বিভাগ যেখানে 1 = 0 যোগ করুন।

একবার সংরক্ষণ করা পদ্ধতি চালান এবং ফিরে যান এবং আপনি যোগ করা এসকিউএল কোড মুছে ফেলুন। এখন, আপনার সংরক্ষিত পদ্ধতির ফলাফলের সাথে মিলে একটি খালি টেবিল থাকবে। আপনি একটি অস্থায়ী টেবিল জন্য "তৈরি হিসাবে স্ক্রিপ্ট টেবিল" বা কেবল যে টেবিলের মধ্যে সরাসরি সন্নিবেশ করতে পারে।


এই সংরক্ষিত প্রসেস কাজ করে:

CREATE PROCEDURE [dbo].[ExecIntoTable]
(
    @tableName          NVARCHAR(256),
    @storedProcWithParameters   NVARCHAR(MAX)
)
AS
BEGIN
    DECLARE @driver         VARCHAR(10)
    DECLARE @connectionString   NVARCHAR(600)
    DECLARE @sql            NVARCHAR(MAX)
    DECLARE @rowsetSql      NVARCHAR(MAX)

    SET @driver = '''SQLNCLI'''

    SET @connectionString = 
        '''server=' + 
            CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256)) + 
            COALESCE('\' + CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(256)), '') + 
        ';trusted_connection=yes'''

    SET @rowsetSql = '''EXEC ' + REPLACE(@storedProcWithParameters, '''', '''''') + ''''

    SET @sql = '
SELECT
    *
INTO 
    ' + @tableName + ' 
FROM
    OPENROWSET(' + @driver + ',' + @connectionString + ',' + @rowsetSql + ')'

    EXEC (@sql)
END
GO

এটি একটি সামান্য পুনর্বিবেচনা: সঞ্চিত পদ্ধতি ফলাফল সারণিতে সন্নিবেশ করান যাতে এটি আসলে কাজ করে।

যদি আপনি এটি একটি অস্থায়ী টেবিলের সাথে কাজ করতে চান তবে আপনাকে ##GLOBAL টেবিলটি ব্যবহার করতে হবে এবং পরে এটি ছেড়ে দিতে হবে।


আমি নিম্নলিখিত কাজ করবে

  1. তৈরি করুন (এসপি রূপান্তর করুন) একটি ইউডিএফ (টেবিল মান UDF)।

  2. select * into #tmpBusLine from dbo.UDF_getBusinessLineHistory '16 Mar 2009'


যদি OPENROWSET আপনাকে সমস্যার সৃষ্টি করে তবে ২01২ সাল থেকে অন্য একটি উপায় রয়েছে; sys.dm_exec_describe_first_result_set_for_object ব্যবহার করুন, এখানে উল্লেখ করা হয়েছে: কলামের নাম এবং সংরক্ষিত পদ্ধতির ধরনগুলি পুনরুদ্ধার করবেন?

প্রথম, অস্থায়ী জন্য এসকিউএল জেনারেট করার জন্য এই সংরক্ষিত পদ্ধতি তৈরি করুন

CREATE PROCEDURE dbo.usp_GetStoredProcTableDefinition(
    @ProcedureName  nvarchar(128),
    @TableName      nvarchar(128),
    @SQL            nvarchar(max) OUTPUT
)
AS
SET @SQL = 'CREATE TABLE ' + @tableName + ' ('

SELECT @SQL = @SQL + '['+name +'] '+ system_type_name +''  + ','
        FROM sys.dm_exec_describe_first_result_set_for_object
        (
          OBJECT_ID(@ProcedureName), 
          NULL
        );

--Remove trailing comma
SET @SQL = SUBSTRING(@SQL,0,LEN(@SQL))    
SET @SQL =  @SQL +')'

পদ্ধতিটি ব্যবহার করতে, নিম্নলিখিত পদ্ধতিতে এটি কল করুন:

DECLARE     @SQL    NVARCHAR(MAX)

exec dbo.usp_GetStoredProcTableDefinition
    @ProcedureName='dbo.usp_YourProcedure',
    @TableName='##YourGlobalTempTable',@SQL = @SQL OUTPUT

INSERT INTO ##YourGlobalTempTable
EXEC    [dbo].usp_YourProcedure

select * from ##YourGlobalTempTable

মনে রাখবেন আমি একটি গ্লোবাল অস্থায়ী টেবিল ব্যবহার করছি। যেহেতু গতিশীল এসকিউএল চালানোর জন্য EXEC ব্যবহার করে এটি নিজস্ব অধিবেশন তৈরি করে, তাই একটি সাধারণ অস্থায়ী টেবিল কোনও পরবর্তী কোডের সুযোগ ছাড়িয়ে যাবে। যদি একটি বিশ্বব্যাপী অস্থায়ী টেবিল একটি সমস্যা হয় তবে আপনি একটি সাধারণ অস্থায়ী টেবিল ব্যবহার করতে পারেন, তবে পরবর্তী কোনও এসকিউএলটি গতিশীল হতে হবে, যা EXEC বিবৃতির দ্বারাও কার্যকর হয়।


সবচেয়ে সহজ সমাধান:

CREATE TABLE #temp (...);

INSERT INTO #temp
EXEC [sproc];

যদি আপনি স্কিমাটি জানেন না তবে আপনি নিম্নলিখিতটি করতে পারেন। এই পদ্ধতিতে গুরুতর নিরাপত্তা ঝুঁকি আছে দয়া করে নোট করুন।

SELECT * 
INTO #temp
FROM OPENROWSET('SQLNCLI', 
                'Server=localhost;Trusted_Connection=yes;', 
                'EXEC [db].[schema].[sproc]')

Quassnoi আমাকে বেশিরভাগ উপায় রাখা, কিন্তু এক জিনিস অনুপস্থিত ছিল:

**** আমি সঞ্চিত পদ্ধতিতে পরামিতি ব্যবহার করতে প্রয়োজন। ****

এবং OPENQUERY এই ঘটনার জন্য অনুমতি দেয় না:

সুতরাং আমি সিস্টেমটি কাজ করার একটি উপায় খুঁজে পেয়েছি এবং টেবিল সংজ্ঞাটিকে এত কঠোর করে তুলতে হবে না এবং এটি অন্য কোন সংরক্ষিত পদ্ধতির ভিতরে পুনরায় সংজ্ঞায়িত করতে হবে (এবং অবশ্যই এটি ভাঙতে পারে এমন সুযোগটি গ্রহণ করুন)!

হ্যাঁ, আপনি বগাস ভ্যারাইবলগুলির সাথে OPENQUERY বিবৃতিটি ব্যবহার করে সঞ্চিত পদ্ধতি থেকে ফেরত টেবিল সংজ্ঞাটি গতিশীলভাবে তৈরি করতে পারেন (যতক্ষণ না কোন ফলাফলের ফলাফলটি একই ক্ষেত্রের নম্বর এবং ভাল তথ্য সহ ডেটাসেটের মতো একই অবস্থানে)।

টেবিলটি একবার তৈরি হয়ে গেলে, আপনি সমস্ত দিনের জন্য অস্থায়ী টেবিলের মধ্যে সঞ্চালিত স্টোরটি ব্যবহার করতে পারেন।

এবং নোট (উপরে নির্দেশিত হিসাবে) আপনি তথ্য অ্যাক্সেস সক্ষম করতে হবে,

EXEC sp_serveroption 'MYSERVERNAME', 'DATA ACCESS', TRUE

কোড:

declare @locCompanyId varchar(8)
declare @locDateOne datetime
declare @locDateTwo datetime

set @locDateOne = '2/11/2010'
set @locDateTwo = getdate()

--Build temporary table (based on bogus variable values)
--because we just want the table definition and
--since openquery does not allow variable definitions...
--I am going to use bogus variables to get the table defintion.

select * into #tempCoAttendanceRpt20100211
FROM OPENQUERY(DBASESERVER,
  'EXEC DATABASE.dbo.Proc_MyStoredProc 1,"2/1/2010","2/15/2010 3:00 pm"')

set @locCompanyId = '7753231'

insert into #tempCoAttendanceRpt20100211
EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo

set @locCompanyId = '9872231'

insert into #tempCoAttendanceRpt20100211
EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo

select * from #tempCoAttendanceRpt20100211
drop table #tempCoAttendanceRpt20100211

মূলত সরবরাহ করা তথ্যটির জন্য ধন্যবাদ ... হ্যাঁ, অবশেষে আমাকে এই সমস্ত বোগাস (কঠোর) টেবিল সংজ্ঞায়িত করতে হবে না যখন অন্য কোন সংরক্ষিত পদ্ধতি বা ডেটাবেসে ডেটা ব্যবহার করা হয়, এবং হ্যাঁ আপনিও পরামিতিগুলি ব্যবহার করতে পারেন।

অনুসন্ধান রেফারেন্স ট্যাগ:

  • এসকিউএল 2005 টেম্প টেবিল মধ্যে সংরক্ষিত পদ্ধতি

  • সংরক্ষিত পদ্ধতি এবং পরিবর্তনশীল 2005 সঙ্গে openquery

  • ভেরিয়েবল সঙ্গে openquery

  • টেম্প টেবিল মধ্যে সংরক্ষিত পদ্ধতি চালানো

হালনাগাদ: এটি অস্থায়ী টেবিলগুলির সাথে কাজ করবে না তাই আমি অস্থায়ী টেবিল তৈরি করতে অবলম্বন করতে হয়েছিল।

Bummer নোটিশ : এই অস্থায়ী টেবিল সঙ্গে কাজ করবে না, http://www.sommarskog.se/share_data.html#OPENQUERY

রেফারেন্স: পরবর্তী জিনিস LOCALSERVER সংজ্ঞায়িত করা হয়। এটি উদাহরণস্বরূপ একটি শব্দ মত দেখতে পারে, কিন্তু আসলে এটি শুধুমাত্র একটি নাম। আপনি কিভাবে এটি করবেন:

sp_addlinkedserver @server = 'LOCALSERVER',  @srvproduct = '',
                   @provider = 'SQLOLEDB', @datasrc = @@servername

একটি সংযুক্ত সার্ভার তৈরি করার জন্য, আপনার অবশ্যই কোনও সার্ভারের অনুমতি থাকতে হবে, অথবা নির্দিষ্ট সার্ভারের ভূমিকাগুলি sysadmin বা setupadmin এর সদস্য হতে হবে।

OPENQUERY SQL সার্ভারে একটি নতুন সংযোগ খোলে। এই কিছু প্রভাব আছে:

আপনি OPENQUERY এর সাথে যে পদ্ধতিটি কল করেন তা বর্তমান সংযোগে তৈরি অস্থায়ী টেবিলগুলি উল্লেখ করতে পারে না।

নতুন সংযোগটির নিজস্ব ডিফল্ট ডেটাবেস রয়েছে (sp_addlinkedserver দ্বারা সংজ্ঞায়িত, ডিফল্ট মাস্টার), তাই সমস্ত বস্তুর স্পেসিফিকেশন অবশ্যই একটি ডাটাবেস নাম অন্তর্ভুক্ত করতে হবে।

যদি আপনার কোনও খোলা লেনদেন থাকে এবং আপনি OPENQUERY কল করলে লকগুলি ধরে রাখেন, তথাকথিত পদ্ধতিটি আপনি কী লক করেন তা অ্যাক্সেস করতে পারে না। যদি আপনি সতর্ক না হন তবে আপনি নিজেকে অবরুদ্ধ করবেন।

সংযুক্তির জন্য বিনামূল্যে নয়, তাই একটি কর্মক্ষমতা শাস্তি আছে।


আপনি যদি এসকিউএল ২01২ বা উচ্চতর পর্যায়ে ভাগ্যবান হন তবে আপনি dm_exec_describe_first_result_set_for_object ব্যবহার করতে পারেন

আমি শুধু gotqn দ্বারা উপলব্ধ এসকিউএল সম্পাদনা করেছেন। ধন্যবাদ পেয়েছেন।

এই প্রক্রিয়া নাম হিসাবে একই সঙ্গে একটি বিশ্বব্যাপী টেম্প টেবিল তৈরি করে। টেম্প টেবিল পরে প্রয়োজনীয় হিসাবে ব্যবহার করা যেতে পারে। শুধু পুনরায় নির্বাহ করার আগে এটি ড্রপ ভুলবেন না।

    declare @procname nvarchar(255) = 'myProcedure',
            @sql nvarchar(max) 

    set @sql = 'create table ##' + @procname + ' ('
    begin
            select      @sql = @sql + '[' + r.name + '] ' +  r.system_type_name + ','
            from        sys.procedures AS p
            cross apply sys.dm_exec_describe_first_result_set_for_object(p.object_id, 0) AS r
            where       p.name = @procname

            set @sql = substring(@sql,1,len(@sql)-1) + ')'
            execute (@sql)
            execute('insert ##' + @procname + ' exec ' + @procname)
    end






stored-procedures