এসকিউএল সার্ভার অঙ্গীকারের পূর্বে লেনদেনের জন্য ডিডিএলকে (দৃশ্যমান করার) অনুমতি দেয়?


9

পোস্টগ্রেএসকিউএল-এ আমি কিছু পরীক্ষার ডেটা সহ একটি টেবিল তৈরি করতে পারি এবং তারপরে কোনও লেনদেনে এটিকে আলাদা ধরণের নতুন কলামে স্থানান্তরিত করে ফলস্বরূপ একটি টেবিল-পুনরায় লেখার ফলস্বরূপ COMMIT,

CREATE TABLE foo ( a int );
INSERT INTO foo VALUES (1),(2),(3);

অনুসরণ করেছেন,

BEGIN;
  ALTER TABLE foo ADD COLUMN b varchar;
  UPDATE foo SET b = CAST(a AS varchar);
  ALTER TABLE foo DROP COLUMN a;
COMMIT;

তবে মাইক্রোসফ্টের এসকিউএল সার্ভারে একই জিনিসটি একটি ত্রুটি তৈরি করেছে বলে মনে হচ্ছে। এই ওয়ার্কিং ডিবি ফিডেলের সাথে তুলনা করুন যেখানে ADD(কলাম) কমান্ড লেনদেনের বাইরে রয়েছে,

-- txn1
BEGIN TRANSACTION;
  ALTER TABLE foo ADD b varchar;
COMMIT;

-- txn2
BEGIN TRANSACTION;
  UPDATE foo SET b = CAST( a AS varchar );
  ALTER TABLE foo DROP COLUMN a;
COMMIT;

এই ডিবি ফিডল যা কাজ করে না,

-- txn1
BEGIN TRANSACTION;
  ALTER TABLE foo ADD b varchar;
  UPDATE foo SET b = CAST( a AS varchar );
  ALTER TABLE foo DROP COLUMN a;
COMMIT;

পরিবর্তে ত্রুটি

Msg 207 Level 16 State 1 Line 2
Invalid column name 'b'.

এই লেনদেনটি দৃশ্যমান করে তোলার জন্য কি ডিডিএল সম্পর্কিত পোস্টগ্র্রেএসকিউএল এর মতো আচরণ করা যায়?

উত্তর:


17

সাধারণত বলছি, না। এসকিউএল সার্ভার বাস্তবায়নের আগে পুরো ব্যাচটি বর্তমান স্কোপে সংকলন করে যাতে রেফারেন্সযুক্ত সত্তাগুলির উপস্থিতি থাকতে হয় (বিবৃতি-স্তরের পুনঃসংশোধনগুলি পরেও ঘটতে পারে)। মূল ব্যতিক্রম হ'ল ডিফার্ড নেম রেজোলিউশন তবে এটি কলামগুলিতে নয়, টেবিলগুলিতে প্রযোজ্য:

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

সাধারণ কাজের ক্ষেত্রগুলি গতিশীল কোড (জো এর উত্তর হিসাবে ) জড়িত করে , বা ডিএমএল এবং ডিডিএলকে পৃথক ব্যাচে বিভক্ত করে।

এই নির্দিষ্ট ক্ষেত্রে আপনি লিখতে পারেন:

BEGIN TRANSACTION;

    ALTER TABLE dbo.foo
        ALTER COLUMN a varchar(11) NOT NULL
        WITH (ONLINE = ON);

    EXECUTE sys.sp_rename
        @objname = N'dbo.foo.a',
        @newname = N'b',
        @objtype = 'COLUMN';

COMMIT TRANSACTION;

আপনি এখনও bএকই ব্যাচ এবং সুযোগে নাম পরিবর্তন করা কলামটি অ্যাক্সেস করতে পারবেন না তবে এটি কাজটি সম্পন্ন করে।

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


12

এটি কি আপনি খুঁজছেন?

BEGIN TRANSACTION;
  ALTER TABLE foo ADD b varchar;
  EXEC sp_executesql N'UPDATE foo SET b = CAST( a AS varchar )';
  ALTER TABLE foo DROP COLUMN a;
COMMIT;

2

পল হোয়াইটের উত্তরের "সাধারণভাবে কোনও বিবৃতি" না দেওয়ার জন্য, আমি আশা করি নিম্নলিখিতটি প্রশ্নের সরাসরি উত্তর দেবে তবে এ জাতীয় প্রক্রিয়াটির পদ্ধতিগত সীমাবদ্ধতা প্রদর্শন করে এবং আপনাকে এমন পদ্ধতি থেকে দূরে সরিয়ে দেয় যেগুলি সহজ ব্যবস্থাপনায় ndণ দেয় না এবং প্রকাশ করতে পারে না ঝুঁকি।

এটা তোলে করতে DDL একই সময় আপনি DML তৈরি করছেন পরিবর্তন না করতে অনেকবার উল্লেখ করা। সমর্থনযোগ্যতা বজায় রাখতে এবং স্প্যাগেটি স্ট্রিংয়ের পরিবর্তনগুলি এড়ানোর জন্য ভাল প্রোগ্রামিং এই ফাংশনগুলিকে পৃথক করে।

এবং পল যেমন সংক্ষেপে নির্দেশ করেছেন, এসকিউএল সার্ভার ব্যাচগুলিতে কাজ করে ।

এখন, যারা এই কাজটির বিষয়ে সন্দেহ করেন তাদের পক্ষে এটি সম্ভবত আপনার উদাহরণে আসে না তবে 2017 এর মতো কিছু সংস্করণ এটি কার্যকরভাবে কাজ করতে পারে! প্রমাণ এখানে: এখানে চিত্র বর্ণনা লিখুন

[পরীক্ষার কোড - এসকিউএল সার্ভারের বহু সংস্করণে কাজ করতে পারে না]

USE master
GO
CREATE TABLE foo (a VARCHAR(11) )
GO
BEGIN TRANSACTION;
    INSERT INTO dbo.foo (a)
    VALUES ('entry')
/*****
[2] Check Values
*****/
    SELECT a FROM dbo.foo
/*****
[3] Add Column
*****/
    ALTER TABLE dbo.foo
        ADD b VARCHAR(11)
/*****
[3] Insert value into this new column in the same batch
-- Again, this is just an example. Please do not do this in production
*****/
    IF EXISTS (SELECT * FROM sys.columns WHERE object_ID('foo') = object_id
            AND name = 'b')
        INSERT INTO dbo.foo (b)
        VALUES ('d')
COMMIT TRANSACTION;
/*****
[4] SELECT outside transaction
-- this will fail
*****/
    --IF EXISTS (SELECT * FROM sys.columns WHERE object_ID('foo') = object_id
    --      AND name = 'b')
    --  SELECT b FROM dbo.foo
-- this will work...but a SELECT * ???
IF EXISTS (SELECT * FROM sys.columns WHERE object_ID('foo') = object_id
            AND name = 'b')
        SELECT * FROM dbo.foo

DROP TABLE dbo.foo

[উপসংহার]

সুতরাং হ্যাঁ আপনি @AndriyM হিসাবে এসকিউএল সার্ভারের নির্দিষ্ট সংস্করণ বা প্যাচগুলির জন্য একই ব্যাচে ডিডিএল এবং ডিএমএল সম্পাদন করতে পারেন - এসকিউএল 2017 এ ডিবিফিডেল উল্লেখ করেছে, তবে সমস্ত ডিএমএল সমর্থিত নয় এবং এমন কোনও গ্যারান্টি নেই যে এটি সর্বদা ঘটবে। যদি এটি কাজ করে, এটি আপনার এসকিউএল সার্ভারের সংস্করণটির বিপর্যয় হতে পারে এবং আপনি নতুন সংস্করণে প্যাচ বা মাইগ্রেট করার সময় এটি নাটকীয় সমস্যা সৃষ্টি করতে পারে।

  • এছাড়াও, সাধারণভাবে আপনার ডিজাইনের পরিবর্তনের প্রত্যাশা করা উচিত। আমি কোনও টেবিলে কলামগুলি সংশোধন / যুক্ত করার উদ্বেগগুলি বুঝতে পারি, তবে আপনি এই চারপাশে সঠিকভাবে নকশা করতে পারেন design

[অতিরিক্ত ক্রেডিট]

পল যেমন বলেছিলেন, যেমন বিদ্যমান উপস্থিতির বক্তব্য, আপনার কোডের পরবর্তী পদক্ষেপে যাওয়ার আগে কোড বৈধ করার জন্য প্রচুর অন্যান্য উপায় রয়েছে।

  • উপস্থিতি বিবৃতি আপনাকে কোড তৈরি করতে সহায়তা করতে পারে যা এসকিউএল সার্ভারের সমস্ত সংস্করণে কাজ করে
  • এটি একটি বুলিয়ান ফাংশন যা এক বিবৃতিতে জটিল চেকগুলির অনুমতি দেয়

না, আপনি একই কমে যেখানে কলাম তৈরি করছেন সেখানে আপনি যদি এটি করছেন তবে নতুন কলামে intoোকানো যাবে না । আরও সাধারণভাবে, আপনি কেবলমাত্র সেগুলি / সেগুলি তৈরি করার পরে আপনি একই ব্যাচে স্থায়ীভাবে রেফারেন্স দিতে পারবেন না b এই ক্ষেত্রে যদি উপস্থিতি কৌশলটি কাজ করে না। হয় गतिशीलভাবে ডিএমএলকে অনুরোধ করুন বা অন্য ব্যাচে করুন।
অ্যান্ড্রি এম

@ অ্যান্ড্রিএম দুঃখিত, ভুলভাবে ডিবিফিডাল সম্পর্কে একটি বিবৃতি দিয়েছেন। তবে আপনি কি নিজের ইনস্ট্যান্স এ চেষ্টা করে দেখেছেন? এটি 2017 এসপি 1 এ কাজ করে। আমি একটি জিআইএফ আপলোড করব, তবে আপনি কি এটি আপনার সিস্টেমে পরীক্ষা করেছেন?
clifton_h

i.imgur.com/fhAC7lB.png আপনি আসলে বলতে পারেন যে এটি bসন্নিবেশ বিবৃতিতে avyেউয়ের লাইনের উপর ভিত্তি করে সংকলন করবে না । আমি এসকিউএল সার্ভার 2014
অ্যান্ড্রি এম

পছন্দ করুন আমি এটি আগে কাজটিকে প্রভাবিত করে দেখেছি এবং এটি এসকিউএল সার্ভারের কয়েকটি সংস্করণে যেমন এসকিউএল সার্ভার 2017 উল্লেখ করেছিলাম তে এটি কাজ করে।
clifton_h

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