টিএসকিউএলে টেবিল তৈরি স্ক্রিপ্ট উত্পন্ন করার কোনও উপায় আছে কি?


22

নিখুঁতভাবে টি-এসকিউএলে বিদ্যমান সারণী থেকে একটি স্ক্রিপ্ট তৈরি করার কোনও উপায় রয়েছে (এটি এসএমও ব্যবহার ছাড়াই হয়, যেহেতু টি-এসকিউএল এসএমও ব্যবহার করে না)। আসুন একটি সঞ্চিত প্রক্রিয়া বলুন যা একটি সারণির নাম গ্রহণ করে এবং একটি স্ট্রিং প্রদান করে যা প্রদত্ত টেবিলের জন্য তৈরি স্ক্রিপ্ট রয়েছে?

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

বর্তমানে আমাকে সমস্ত ডাটাবেস জুড়ে একটি সারণী থেকে একটি নির্বাচন করার উপায় খুঁজে বের করতে হবে। আমি ডাকা একটি টেবিলের মধ্যে সমস্ত ডাটাবেস নাম রেকর্ড করেছি Databaseesএবং আমি তাদের সকলের উপর একটি নির্বাচিত বিবৃতি কার্যকর করতে নিম্নলিখিত স্ক্রিপ্ট লিখেছি:

IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp

select * into #tmp from Database1.dbo.Table1 where 1=0
DECLARE @statement nvarchar(max) = 
  N'insert into #tmp select * from Table1 where Column1=0 and Cloumn2 =1'

DECLARE @LastDatabaseID INT
SET @LastDatabaseID = 0

DECLARE @DatabaseNameToHandle varchar(60)
DECLARE @DatabaseIDToHandle int

SELECT TOP 1 @DatabaseNameToHandle = Name,
@DatabaseIDToHandle = Database_Ref_No
FROM Databasees
WHERE Database_Ref_No > @LastDatabaseID
ORDER BY Database_Ref_No

WHILE @DatabaseIDToHandle IS NOT NULL
BEGIN

  DECLARE @sql NVARCHAR(MAX) = QUOTENAME(@DatabaseNameToHandle) + '.dbo.sp_executesql'
  EXEC @sql @statement

  SET @LastDatabaseID = @DatabaseIDToHandle
  SET @DatabaseIDToHandle = NULL

  SELECT TOP 1 @DatabaseNameToHandle = Name,
  @DatabaseIDToHandle = Database_Ref_No
  FROM Databasees
  WHERE Database_Ref_No > @LastDatabaseID
  ORDER BY Database_Ref_No
END

select * from #tmp
DROP TABLE #tmp

তবে উপরের স্ক্রিপ্টটি নিম্নলিখিত বার্তায় ব্যর্থ হয়েছে:

সারণি '# টিএমপি'-তে পরিচয় কলামের জন্য একটি স্পষ্ট মান কেবল তখনই নির্দিষ্ট করা যেতে পারে যখন কোনও কলাম তালিকা ব্যবহার করা হয় এবং IDENTITY_INSERT চালু থাকে।

এটি যুক্ত করা হচ্ছে:

SET IDENTITY_INSERT #tmp ON

সাহায্য করে না, যেহেতু, আমি কলাম তালিকাটি নির্দিষ্ট করতে এবং এটি জেনেরিক রাখতে পারি না।

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

সুতরাং আমি ভেবেছিলাম যে আমি যদি আমার টি-এসকিউএল কোডে তৈরি টেবিল স্ক্রিপ্টটি পেতে পারি, আমি সনাক্তকরণ কলামটি সরাতে স্ট্রিং ম্যানিপুলেশন এক্সপ্রেশন দিয়ে এটিকে চালিত করতে পারি এবং ফলাফল সেটে ডাটাবেস নামের জন্য একটি কলাম যুক্ত করতে পারি।

আমি চাই তা অর্জনের জন্য কি কেউ তুলনামূলক সহজ উপায় সম্পর্কে ভাবতে পারে?

উত্তর:


28

2007 সালে ফিরে, আমি CREATE TABLEইউআই বা এসএমও ব্যবহার না করে টি-এসকিউএল এর মাধ্যমে একটি স্ক্রিপ্ট উত্পন্ন করার সহজ উপায়ের জন্য জিজ্ঞাসা করেছি । আমাকে সংক্ষেপে প্রত্যাখ্যান করা হয়েছিল

তবে এসকিউএল সার্ভার 2012 এটি খুব সহজ করে তুলেছে। আসুন ভান করি আমাদের একাধিক ডাটাবেস জুড়ে একই স্কিমা সহ একটি টেবিল রয়েছে dbo.whatcha:

CREATE TABLE dbo.whatcha
(
  id INT IDENTITY(1,1), 
  x VARCHAR(MAX), 
  b DECIMAL(10,2), 
  y SYSNAME
);

নিম্নলিখিত ক্রিপ্ট প্রতিটি কলামের (এবং সম্পত্তি উপেক্ষা করে ) এর জন্য সঠিক ডেটা ধরণের পুনরুদ্ধার করতে নতুন sys.dm_exec_describe_first_results_setগতিশীল পরিচালনা ফাংশন ব্যবহার করে IDENTITY। এটি আপনার প্রয়োজন # টিএমপি টেবিলটি তৈরি করে, আপনার তালিকার প্রতিটি ডাটাবেস থেকে সন্নিবেশ করায় এবং তারপরে # টিএমপি থেকে সমস্ত একক গতিশীল এসকিউএল ব্যাচের মধ্যে এবং একটি WHILEলুপ ব্যবহার না করে নির্বাচন করে (এটি এটি আরও ভাল করে তোলে না, কেবল সহজ সরল দেখুন এবং আপনাকে Database_Ref_Noপুরোপুরি উপেক্ষা করতে পারবেন :-))।

SET NOCOUNT ON;

DECLARE @sql NVARCHAR(MAX), @cols NVARCHAR(MAX) = N'';

SELECT @cols += N',' + name + ' ' + system_type_name
  FROM sys.dm_exec_describe_first_result_set(N'SELECT * FROM dbo.whatcha', NULL, 1);

SET @cols = STUFF(@cols, 1, 1, N'');

SET @sql = N'CREATE TABLE #tmp(' + @cols + ');'

DECLARE @dbs TABLE(db SYSNAME);

INSERT @dbs VALUES(N'db1'),(N'db2');
  -- SELECT whatever FROM dbo.databases

SELECT @sql += N'
  INSERT #tmp SELECT ' + @cols + ' FROM ' + QUOTENAME(db) + '.dbo.tablename;'
  FROM @dbs;

SET @sql += N'
  SELECT ' + @cols + ' FROM #tmp;';

PRINT @sql;
-- EXEC sp_executesql @sql;

ফলাফল PRINTআউটপুট:

CREATE TABLE #tmp(id int,x varchar(max),b decimal(10,2),y nvarchar(128));
  INSERT #tmp SELECT id,x,b,y FROM [db1].dbo.tablename;
  INSERT #tmp SELECT id,x,b,y FROM [db2].dbo.tablename;
  SELECT id,x,b,y FROM #tmp;

যখন আপনি আত্মবিশ্বাসী হন যে এটি আপনার প্রত্যাশা মতোই করছে, কেবলমাত্র অস্বস্তি করুন EXEC

(এটি আপনাকে বিশ্বাস করে যে স্কিমাটি একই রকম; এটি এক বা একাধিক সারণী পরিবর্তন করা হয়েছে যা যাচাই করে না এবং ফলস্বরূপ ব্যর্থ হতে পারে))


কেন যে পরিচয় চশমা উত্পন্ন করে না?
আউটস্লটম সন্ধান করুন

1
@ কিলান্নি আপনি পুরো উত্তরটি পড়েছিলেন, আমি যেখানে অংশটির বিষয়ে কথা বলি কেন আমরা পরিচয়ের সম্পত্তিটিকে উপেক্ষা করছি?
অ্যারন বারট্রান্ড

আমার পুরো টেবিল সংজ্ঞা প্রয়োজন (পরিচয়, সূচকগুলি, সীমাবদ্ধতাগুলি সহ ..)। ধন্যবাদ, আমি এই দুর্দান্ত স্ক্রিপ্টটি পেয়েছি
স্ট্রোয়ার্জেজেজ

@ কিল্যানি গ্রেট স্পষ্টত, আপনার প্রয়োজন এই প্রশ্নের প্রয়োজনের সাথে মেলে না। তাদের পরিচয় ছাড়াই টেবিলের একটি অনুলিপি প্রয়োজন কারণ তারা এটি বিদ্যমান ডাটা অনুলিপি করতে ব্যবহার করছিল, নতুন সারি তৈরি করে না।
অ্যারন বারট্র্যান্ড

হারুন, এটি একটি চিম্টিতে একটি মার্জিত সমাধান যেখানে আপনার কী ইত্যাদির দরকার নেই ...
GWR

5

কোনও টেবিলের সম্পূর্ণ তৈরি স্ক্রিপ্ট উত্পন্ন করা সম্ভব T-SQL নয়। কমপক্ষে সেখানে কোনও বিল্ড নেই। আপনি সবসময় তথ্যের মধ্য দিয়ে নিজের "জেনারেটর" লিখতে পারেন sys.columns

তবে আপনার ক্ষেত্রে আপনার সম্পূর্ণ তৈরি স্ক্রিপ্ট পাওয়ার দরকার নেই। আপনাকে SELECT INTOকেবল পরিচয় সম্পত্তি অনুলিপি করা থেকে বিরত রাখা দরকার । এটি করার সহজতম উপায় হ'ল সেই কলামটিতে একটি গণনা যুক্ত করা। পরিবর্তে তাই

select * into #tmp from Database1.dbo.Table1 where 1=0

আপনার লিখতে হবে

select id*0 as id, other, column, names into #tmp from Database1.dbo.Table1 where 1=0

এই বিবৃতিটি তৈরি করতে আপনি এই এসকিউএল ফিডেলের মতো আবার সিএসক্লামগুলি ব্যবহার করতে পারেন

এমএস এসকিউএল সার্ভার ২০০৮ স্কিমা সেটআপ :

CREATE TABLE dbo.testtbl(
    id INT IDENTITY(1,1),
    other NVARCHAR(MAX),
    [column] INT,
    [name] INT
);

দুটি কলাম আমরা প্রয়োজন হয় nameএবং is_identity: ক্যোয়ারী 1 :

SELECT name,is_identity
  FROM sys.columns
 WHERE object_id = OBJECT_ID('dbo.testtbl');

ফলাফল :

|   NAME | IS_IDENTITY |
|--------|-------------|
|     id |           1 |
|  other |           0 |
| column |           0 |
|   name |           0 |

এটির সাহায্যে আমরা CASEকলাম তালিকার জন্য প্রতিটি কলাম তৈরি করতে একটি বিবৃতি ব্যবহার করতে পারি :

প্রশ্ন 2 :

SELECT ','+ 
    CASE is_identity
    WHEN 1 THEN QUOTENAME(name)+'*0 AS '+QUOTENAME(name)
    ELSE QUOTENAME(name)
    END
  FROM sys.columns
 WHERE object_id = OBJECT_ID('dbo.testtbl');

ফলাফল :

|        COLUMN_0 |
|-----------------|
| ,[id]*0 AS [id] |
|        ,[other] |
|       ,[column] |
|         ,[name] |

একটি সামান্য এক্সএমএল কৌতুক সহ আমরা পুরো কলাম তালিকাটি পেতে একসাথে এই সমস্তকে সম্মতি জানাতে পারি:

প্রশ্ন 3 :

SELECT STUFF((
  SELECT ','+ 
      CASE is_identity
      WHEN 1 THEN QUOTENAME(name)+'*0 AS '+QUOTENAME(name)
      ELSE QUOTENAME(name)
      END
    FROM sys.columns
   WHERE object_id = OBJECT_ID('dbo.testtbl')
   ORDER BY column_id
     FOR XML PATH(''),TYPE
  ).value('.','NVARCHAR(MAX)'),1,1,'')

ফলাফল :

|                               COLUMN_0 |
|----------------------------------------|
| [id]*0 AS [id],[other],[column],[name] |

মনে রাখবেন, আপনি ডায়নামিক এসকিউএল ব্যবহার করে একটি # টেম্প টেবিল তৈরি করতে পারবেন না এবং আপনার গতিশীল এসকিউএল স্টেটমেন্টটি শেষ হয়ে গেলে # টেম্প টেবিলটি সুযোগের বাইরে চলে যাওয়ায় এটি বিবৃতিটির বাইরে ব্যবহার করতে পারবেন না। সুতরাং আপনাকে হয় আপনার সমস্ত কোড একই গতিশীল এসকিউএল স্ট্রিংয়ে চেপে ফেলে বা একটি বাস্তব টেবিল ব্যবহার করতে হবে। আপনি যদি একই সাথে এই স্ক্রিপ্ট / পদ্ধতিগুলির একাধিক চালনা করতে সক্ষম হন তবে আপনার প্রয়োজন আমাদের এলোমেলো টেবিলের নাম, অন্যথায় তারা একে অপরের দিকে পদক্ষেপ নেবে। এর মতো কিছুতে QUOTENAME(N'temp_'+CAST(NEWID() AS NVARCHAR(40))যথেষ্ট ভাল নাম করা উচিত।


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


1
আপনি একটি # টেম্প টেবিল তৈরি করতে পারেন এবং তারপরে এটি ঠিক গতিশীল এসকিউএল থেকে উল্লেখ করতে পারেন। এটি কেবলমাত্র আপনি যদি সেই সুযোগে তৈরি করেন যে গতিশীল এসকিউএল কার্যকর করার পরে এটি দৃশ্যমান নয়।
অ্যারন বারট্র্যান্ড

3

এসকিউএল সার্ভারসেন্ট্রাল প্রবন্ধে এটি অর্জনের জন্য একটি ভাল স্ক্রিপ্ট রয়েছে:

স্ক্রিপ্টের সর্বশেষতম সংস্করণটি এখানে পাঠ্য হিসাবেও পাওয়া যাবে (স্ট্রোরেজ ডটকম)।

আমি এখানে সমস্ত স্ক্রিপ্ট অন্তর্ভুক্ত করার উপায় ছিল, কারণ এটি আমার জন্য কাজ করে। স্ক্রিপ্টটি এখানে আটকানোর জন্য খুব দীর্ঘ।

কপিরাইট নোটিশ:

--#################################################################################################
-- copyright 2004-2013 by Lowell Izaguirre scripts*at*stormrage.com all rights reserved.
-- http://www.stormrage.com/SQLStuff/sp_GetDDL_Latest.txt
--Purpose: Script Any Table, Temp Table or Object
--
-- see the thread here for lots of details: http://www.sqlservercentral.com/Forums/Topic751783-566-7.aspx

-- You can use this however you like...this script is not rocket science, but it took a bit of work to create.
-- the only thing that I ask
-- is that if you adapt my procedure or make it better, to simply send me a copy of it,
-- so I can learn from the things you've enhanced.The feedback you give will be what makes
-- it worthwhile to me, and will be fed back to the SQL community.
-- add this to your toolbox of helpful scripts.
--#################################################################################################

-1

আপনি CREATE TABLEডেটা থেকে ডায়নামিক এসকিউএল ব্যবহার করে মোটামুটি উত্পন্ন করতে পারেন INFORMATION_SCHEMA.COLUMNS

আপনার যদি সীমাবদ্ধতা ইত্যাদি যুক্ত করতে হয় তবে আপনাকে অন্য কয়েকটি INFORMATION_SCHEMAমতামত থেকে তথ্য যুক্ত করতে হবে ।

মাইক্রোসফ্ট ডকুমেন্টেশন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.