একক কোয়েরি ব্যবহার করে কীভাবে সন্নিবেশ বা আপডেট করবেন?


26

আমার কাছে একটি টেবিল পরীক্ষা রয়েছে যাতে কলাম আইডি রয়েছে যা প্রাথমিক কী এবং অটো বর্ধিত এবং নাম। আমি কোনও নতুন রেকর্ড সন্নিবেশ করতে চাই যদি কেবল কোনও রেকর্ড না থাকে তবে আনড করতে পারি example উদাহরণস্বরূপ

ইনপুটটি আইডি = 30122 এবং নাম = জন

যদি 30122 আইডি সহ রেকর্ড থাকে তবে আমি জনের কাছে নাম কলামটি আপডেট করেছি, যদি কোনও রেকর্ড না থাকে তবে আমি একটি নতুন রেকর্ড সন্নিবেশ করিয়েছি।

আমি 2 টি প্রশ্নের মতো ব্যবহার করতে পারি

select * from test where id=30122

যদি এর কিছু রেকর্ড থাকে তবে আমি ব্যবহার করতে পারি update test set name='john' where id=3012

বা যদি এর রেকর্ড না থাকে তবে আমি ব্যবহার করতে পারি

insert into test(name) values('john')

কিন্তু আমি একক কোয়েরি ব্যবহার করতে চেয়েছি?

এটা সম্ভব কিনা কেউ বলতে পারেন?


1
But I wanted to use single query?কেন?
অ্যারন বারট্রান্ড

@ অ্যারনবার্ট্রান্ড আমার পিছনের প্রান্তটি জাভা ব্যবহার করে বিকশিত হয়েছে o সুতরাং আমি যদি 2 টি কিউরি ব্যবহার করি তবে আমাকে 2 বার ডিবিতে আঘাত করতে হবে o সুতরাং যদি এটি একটি একক ক্যোয়ারী ব্যবহার করে করা যায় তবে কেন 2 টি প্রশ্ন ব্যবহার করবেন
স্প্রিংলায়ার্নার

1
জাভা কোনও সঞ্চিত প্রক্রিয়া, বা দুটি স্টেটমেন্টের সাথে একটি একক ব্যাচকে সমর্থন করে না যা কেবলমাত্র একটি ডাটাবেসে হিট লাগে?
অ্যারন বারট্র্যান্ড

@ অ্যারোনবার্ট্র্যান্ড আপনি কীভাবে স্কেল সার্ভার ২০০৮ বা তার পরে এটি পরিচালনা করবেন তার একটি উদাহরণ দিতে পারেন?
agগলই 22

1
@ agগলই 22 আমি নীচে বিজয়ের উত্তরে দ্বিতীয় উদাহরণটি ব্যবহার করব। আমি এখনও MERGEকোনও সংস্করণ, এমনকি এসকিউএল সার্ভার 2019 বেছে নেব না that এখানে এর কিছু পটভূমি
হারুন বারট্রান্ড

উত্তর:


41

আপনি এটি চেষ্টা করতে পারেন

IF EXISTS(select * from test where id=30122)
   update test set name='john' where id=3012
ELSE
   insert into test(name) values('john');

আরও ভাল পারফরম্যান্সের জন্য অন্যান্য পদ্ধতি হ'ল

update test set name='john' where id=3012
IF @@ROWCOUNT=0
   insert into test(name) values('john');

এবং স্কিমা উপসর্গটি কিক করার জন্য এই খারাপ অভ্যাসগুলি পড়ুন


4
প্রথম উদাহরণটি অপ্রয়োজনীয় এবং প্রায়শই অচলাবস্থার দিকে নিয়ে যেতে পারে - আমি এটিকে মোটেই প্রস্তাব দেব না।
অ্যারন বারট্রান্ড

@ অ্যারনবার্ট্র্যান্ড কি বিস্তৃতভাবে যত্নশীল? ধন্যবাদ
হেক্সো

5
@ স্ল্যাপই শিওর, প্রথম উদাহরণে আপনি বলছেন: "আরে, এসকিউএল সার্ভার, এই আইডি সহ কোনও সারি আছে?" এসকিউএল সার্ভার সম্ভবত একটি স্ক্যান ব্যবহার করে সারিটি সন্ধান করতে চলে যায় এবং তারপরে উত্তরটি নিয়ে ফিরে আসে। "কেন, হ্যাঁ, ব্যবহারকারী, আমি এই আইডি দিয়ে একটি সারি রাখি!" তারপরে আপনি বলবেন, "ঠিক আছে, এসকিউএল সার্ভার, আবার সেই সারিটি সন্ধান করুন , তবে এবার এটি আপডেট করুন!" আপনি কীভাবে দেখছেন যে দুবার অনুসন্ধান বা স্ক্যান করা ব্যর্থ হয়? আপনি কি ভাবতে পারেন যে যদি কোনও ব্যবহারকারী এসকিউএল সার্ভারকে একটি সারির অস্তিত্ব সম্পর্কে একই প্রশ্ন জিজ্ঞাসা করে, আপনি এটি সম্পর্কে কিছু করার আগে?
অ্যারন বারট্রান্ড

ধন্যবাদ, আমি ঠিক দেখতে পাচ্ছি না যে দ্বিতীয়টি কেন না থাকায় প্রথম অচলাবস্থার হুমকি দেওয়া হচ্ছে? উভয়ই একাধিক বিবৃতি ধারণ করে যা সম্পূর্ণ লক দিয়ে চালানো না হলে বাধা দেওয়া যায়। আমি কি ভূল?
হেক্সো

2
@ 0x25b3 এটি এমন নয় যে একটিকে অচলাবস্থার দ্বারা হুমকি দেওয়া হয়েছিল এবং অন্যটি তা নয়, প্রথম উদাহরণটি তাদের কাছে অনেক বেশি প্রবণ। উভয় ক্ষেত্রে আপনার পুরো এবং যথাযথ লেনদেনের মোড়ক থাকা উচিত, তবে লোকেরা তা করে না ...
অ্যারন বারট্রান্ড

17

এসকিউএল সার্ভার 2008 বা তার পরে ধরে ধরে, আপনি ব্যবহার করতে পারেন MERGE:

টেবিল

CREATE TABLE dbo.Test
(
    id integer NOT NULL,
    name varchar(30) NULL,

    CONSTRAINT PK_dbo_Test__id
        PRIMARY KEY CLUSTERED (id)
);

প্রশ্ন

MERGE dbo.Test WITH (SERIALIZABLE) AS T
USING (VALUES (3012, 'john')) AS U (id, name)
    ON U.id = T.id
WHEN MATCHED THEN 
    UPDATE SET T.name = U.name
WHEN NOT MATCHED THEN
    INSERT (id, name) 
    VALUES (U.id, U.name);

SERIALIZABLEইঙ্গিতটি জন্য প্রয়োজন উচ্চ সম্পাতবিন্দু অধীনে সঠিক অপারেশন

মাইকেল জে স্বার্টের দ্বারা সাধারণ পদ্ধতির তুলনা আপনি এখানে পাবেন:

মাইথবাস্টিং: সমবর্তী আপডেট / সন্নিবেশ সমাধানগুলি



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