SQL सर्वर 2008 - दो तालिकाओं में, एक तालिका में नए बनाए गए रिकॉर्ड से आईडी डालें

मेरे पास तीन टेबल हैं:

DECLARE @UserTable TABLE(
        [UserId] [int] IDENTITY(1,1) NOT NULL,
        UserName varchar(100))

DECLARE @UserRoles TABLE(
        [UserRoleId] [int] IDENTITY(1,1) NOT NULL,
        RoleName varchar(100),
        UserId int)

DECLARE @UserProjects TABLE(
        [UserProjectId] [int] IDENTITY(1,1) NOT NULL,
        ProjectName varchar(100),
        UserId int)

मैं क्या करना चाहता हूं, यह है कि जब भी मैं @UserTable में एक नया रिकॉर्ड बनाता हूं, तो मैं उस रिकॉर्ड से आईडी लेना चाहता हूं और @UserRoles में एक नया रिकॉर्ड बनाना चाहता हूं और @UserProjects । एक-एक-एक आधार पर रिकॉर्ड डालने पर, मैं नई आईडी प्राप्त करने के लिए SCOPE_IDENTITY का उपयोग कर सकता हूं, और फिर उस से मूल्य का उपयोग करके द्वितीय और तृतीय प्रविष्टियां कर सकता हूं ...

लेकिन जब मैं @UserTable में 100 रिकॉर्ड्स डालने के साथ ऐसा करने की कोशिश करता हूं, तो यह काम नहीं करेगा क्योंकि यह एक बड़ा सम्मिलन है। इस के बारे में जाने के लिए सबसे अच्छा तरीका क्या है? एक कर्सर का प्रयोग करें? मैं विचारों के लिए खुला हूं, क्योंकि मुझे पहले कभी ऐसा नहीं करना पड़ा था ... यह FOREACH लूप के साथ आसान होगा, लेकिन जहां तक ​​मुझे पता है, एसक्यूएल इन्हें संभाल नहीं पाता है वैसे ही हम जावा या सी # की अपेक्षा करेंगे, है ना?

0
@ मुहम्मद-अली मुझे यकीन नहीं है कि मैं समझता हूं। मेरे पास एक संग्रहीत प्रक्रिया है जो एक अस्थायी तालिका बनाता है, इसमें प्रारंभिक मान डालता है, और उसके बाद उस तालिका को जानकारी के साथ अद्यतन करता है। फिर, मैं अस्थायी तालिका में सभी रिकॉर्ड लेता हूं, और उन्हें किसी अन्य तालिका (उपयोगकर्ता तालिका) में डालता हूं। मैं उपयोगकर्ता टेबल सम्मिलन पर जाने के लिए एक ट्रिगर बनाना चाहता हूं, जो तब भूमिकाओं और प्रोजेक्ट टेबल को पॉप्युलेट करेगा ... लेकिन ट्रिगर बनाने के दौरान मुझे त्रुटियां मिल रही हैं। प्रक्रिया में अन्य कोड के साथ ट्रिगर डालने का सबसे अच्छा स्थान कहां है?
जोड़ा लेखक SalarianEngineer, स्रोत
आपको UserTable पर सम्मिलित ट्रिगर बनाने की आवश्यकता होगी जो उस तालिका में किसी भी संख्या में इन्सर्ट को संभालेगा, अन्य टेबलों में कैस्केडिंग आवेषण करेगा।
जोड़ा लेखक M.Ali, स्रोत

5 उत्तर

जब तक मैं गलत नहीं हूं, आप जो करने की कोशिश कर रहे हैं वह आपकी तालिकाओं पर संदर्भित अखंडता को लागू करता है और कैस्केडिंग कार्यों के लिए खाता है। एक सभ्य लेख यहां दिखाता है जो दिखाता है इसे कैसे सेट करें।

2
जोड़ा
बस मुझे क्या चाहिए, धन्यवाद!
जोड़ा लेखक SalarianEngineer, स्रोत

इस समाधान का प्रयास करें:

-- Parameters
DECLARE @UserName VARCHAR(100), @RoleName VARCHAR(100), @ProjectName VARCHAR(100);
SELECT  @UserName = 'User CocoJambo',
        @RoleName = 'Role MamboJambo',
        @ProjectName = 'Project Jumbo';
-- End of Parameters

DECLARE @NewUserID TABLE (UserID INT);

INSERT  @UserTable (UserName)
OUTPUT  inserted.UserId INTO @NewUserID (UserID)
VALUES  (@UserName);

INSERT  @UserRoles (UserID, RoleName)
SELECT  u.UserId, @RoleName
FROM    @UserTable u;

INSERT  @UserProjects (UserId, ProjectName)
SELECT  u.UserId, @ProjectName
FROM    @UserTable u;
0
जोड़ा
यदि यह समाधान आपकी मदद नहीं करते हैं तो आपको अधिक जानकारी प्रदान करनी चाहिए: उदाहरण के लिए आप किस डेटा (कॉलम) आयात करते हैं? क्या आप एक या अधिक फ़ाइलों को SQL सर्वर डीबी (शायद प्रति फ़ाइल एक फ़ाइल) में आयात करते हैं?
जोड़ा लेखक Bogdan Sahlean, स्रोत

आपको अपने उपयोगकर्ताटेबल पर ट्रिगर को परिभाषित करने की आवश्यकता होगी जो आपके लिए अन्य टेबलों में कैस्केडिंग डालने के लिए कुछ ऐसी चीज करेगा

CREATE Trigger tr_ForInserts
ON UserTable
FOR INSERT
AS
BEGIN
 SET NOCOUNT ON;

   /*Get all the new insert into a temp table */

   SELECT * INTO #TempTable 
   FROM inserted 

 /*Insert Statement to Insert recods in UserRoles Table */

   INSERT INTO UserRoles (Column1,Column2,Column3,...) 
   SELECT  Column1,Column2,Column3
   FROM #TempTable 


 /*Insert Statement to Insert recods in UserProjects Table */ 

   INSERT INTO UserProjects (Column4,Column5,Column6,...) 
   SELECT  Column4,Column5,Column6
   FROM #TempTable 

END
0
जोड़ा
@Shiva कारण मैंने एक temp तालिका का उपयोग किया है यहां देखें कि आपका कोड क्या करता है :) sqlfiddle.com/# ! 3/6fc64/1
जोड़ा लेखक M.Ali, स्रोत
@ शिवा टेबल वैरिएबल अच्छे और तेज़ हैं यदि आप जानते हैं कि आप केवल पंक्तियों की छोटी संख्या डालेंगे, लेकिन क्या होगा यदि आपको बहुत सारी पंक्तियां डालना पड़े जो आपकी सभी मेमोरी खाने को समाप्त कर सकें ??? क्या आप अपनी ट्रिगर की परिभाषा में जाएंगे और जब भी आपको बड़ी संख्या में थोक आवेषण करना होगा तो इसे ट्वीक करें ?? या आप कुछ गणना करेंगे और आपके सभी उपयोगकर्ताओं को यह पता चलेगा कि वे एक समय में कितनी पंक्तियां जोड़ सकते हैं ??? या यह temp तालिकाओं का उपयोग करना बेहतर है और एसक्यूएल सर्वर काम करते हैं :)
जोड़ा लेखक M.Ali, स्रोत
टेम्प्लेट टेबल पर भी यदि आप बहुत सारे डेटा से निपट रहे हैं तो आप ऑपरेशंस को तेज करने के लिए इंडेक्स बना सकते हैं और हां, मुझे सभी परिचालनों के अंत में टेबल छोड़ना चाहिए था। लेकिन मुझे लगता है कि हम सभी ओपी को सही दिशा में रखने की कोशिश कर रहे हैं, सवाल नहीं दे सकते हैं कि वह प्रश्न में दिए गए जानकारी के साथ, इसे अपने डेटाबेस में पेस्ट कॉपी कर सकते हैं।
जोड़ा लेखक M.Ali, स्रोत
एक temp तालिका बनाने और इसमें सबकुछ चुनने की कोई आवश्यकता नहीं है, क्योंकि ओपी केवल आईडी चाहता है।
जोड़ा लेखक Shiva, स्रोत
माना। मैंने बल्क इंसर्ट्स को संबोधित करने के लिए अपना कोड अपडेट किया। फिर भी, आपको एक टेबल वैरिएबल का उपयोग करना चाहिए, न कि टेम्पल टेबल (अधिक ओवरहेड, बड़ा स्कोप इत्यादि)। :)
जोड़ा लेखक Shiva, स्रोत
@ शिवा: टेम्पलेट टेबल जैसे tempdb में टेबल वैरिएबल आबादी में आते हैं, और लॉजिकल टेबल (डालने और हटाए गए) को ट्रिगर करते हैं, tempdb में भी जाते हैं, जिससे एक डालने ट्रिगर (अपडेट ट्रिगर के लिए x3) में tempdb में डेटा दो बार बनाता है। अस्थायी तालिकाओं (एसक्यूएल सर्वर के। डेलानेई के अंदर) और अन्य की तुलना में अस्थायी सारणी चर का उपयोग करने का कोई फायदा नहीं है: cybersql.blogspot.fr/2009/12/…
जोड़ा लेखक ARA, स्रोत

आप इस तरह एक इंसर्ट ट्रिगर लिख सकते हैं। जब आपकी उपयोगकर्ता तालिका में नई पंक्तियां डाली जाती हैं, तो यह ट्रिगर प्रत्येक कथन (प्रत्येक पंक्ति नहीं) के लिए "आग" को निष्पादित करेगा। तो बल्क सम्मिलित होने के मामले में, हमें एक अस्थायी तालिका चर का उपयोग करना होगा जो सभी नए सम्मिलित उपयोगकर्ता आईडी रखेगा और फिर उपयोगकर्ता रोल और उपयोगकर्ताप्रोजेक्ट तालिका में सम्मिलित करेगा।

CREATE TRIGGER trg_Insert_Role_And_Project
ON [UserTable]
FOR INSERT
AS
Begin
    Declare @NewUserIDsTable TABLE
    ( NewUserID INT NOT NULL )

    INSERT INTO @NewUserIDsTable SELECT ID FROM INSERTED

    INSERT INTO UserRoles (UserId, RoleName) 
    SELECT NewUserID, 'Default Role' 
    FROM @NewUserIDsTable 


    INSERT INTO UserProjects (UserId, ProjectName) 
    SELECT NewUserID, 'Default Project'
    FROM @NewUserIDsTable 

End

@UserRoles और @UserProject तालिकाओं में रोलनाम और प्रोजेक्टनाम में डिफ़ॉल्ट मान हैं? इस कोड नमूने के लिए, मैंने 'डिफ़ॉल्ट भूमिका' और 'डिफ़ॉल्ट प्रोजेक्ट' के डिफ़ॉल्ट मानों का उपयोग किया है।

0
जोड़ा
पूछे जाने वाले प्रश्न के लिए तीन तालिकाओं को मनमाने ढंग से बनाया गया था, लेकिन मुझे आपका मतलब है। अनिवार्य रूप से, जब भी कोई नया उपयोगकर्ता बनाया जाता है, और बाद में उपयोगकर्ता पंजीकरण के दौरान मुझे दूसरी 2 टेबलों में रिक्त रिकॉर्ड बनाने की आवश्यकता होती है, तो उन दो तालिकाओं को अपडेट किया जाएगा (इस तरह, रिकॉर्ड पहले से मौजूद है, पंजीकरण के रूप में नहीं है ' ग्राहक आवश्यकताओं के अनुसार एक बैठक में टी को पूरा करना होगा)।
जोड़ा लेखक SalarianEngineer, स्रोत
एक टेम्प तालिका का उपयोग करने का कारण यहां देखें कि आपका कोड क्या करता है :) sqlfiddle.com/#!3/6fc64/1
जोड़ा लेखक M.Ali, स्रोत
@Alain_Deloin आप सही हैं। मैंने थोक सम्मिलित परिदृश्य को संबोधित करने के लिए ट्रिगर को ठीक किया। पृष्ठभूमि के लिए stackoverflow.com/a/5806230/325521 देखें
जोड़ा लेखक Shiva, स्रोत
@ सैलियनइंजिनर सहमत हैं। मैंने अपने जवाब से उस सुझाव को हटा दिया :)
जोड़ा लेखक Shiva, स्रोत
@ NewUserId = INRERTED से उपयोगकर्ता आईडी का चयन करें थोक प्रविष्टि के साथ काम नहीं करेगा (डालने में एकाधिक रिकॉर्ड)
जोड़ा लेखक ARA, स्रोत

असली टेबल्स (और चर नहीं) के साथ आप एक ट्रिगर बना सकते हैं:

CREATE TABLE UserTable( [UserId] [int] IDENTITY(1,1) NOT NULL, UserName varchar(100))

CREATE TABLE UserRoles ( [UserRoleId] [int] IDENTITY(1,1) NOT NULL, RoleName varchar(100), UserId int)

CREATE TABLE UserProjects ( [UserProjectId] [int] IDENTITY(1,1) NOT NULL, ProjectName varchar(100), UserId int)

GO

if object_id('UserTableTrigger') is not null
    drop trigger UserTableTrigger
go
create trigger UserTableTrigger ON Usertable
for INSERT
as
begin
    insert into UserRoles(RoleName,UserId)
    select 'Role_'+UserName, inserted.UserId
    from inserted
    insert into UserProjects(ProjectName,UserId)
    select 'Project_'+UserName, inserted.UserId
    from inserted
end
go

यदि आप इसे देखना चाहते हैं:

insert into UserTable (UserName)
select 'User_'+name from master..spt_values

select * from UserTable
left join UserRoles on UserTable.USerId = UserRoles.UserId
left join UserProjects on UserTable.USerId = UserProjects.UserId
0
जोड़ा