केवल एक आईडी कॉलम वाले तालिका में पंक्तियों को सम्मिलित करना


83

मेरे पास केवल एक कॉलम के साथ एक टेबल प्रशासक है, adminId जो प्राथमिक-कुंजी है। व्यापार नियमों के कारण इसे इस तरह से होना चाहिए।

मैं एक बार और सभी के लिए समझना चाहता हूं कि मैं संग्रहीत प्रक्रियाओं को कैसे लिख सकता हूं जो इस तरह तालिकाओं में मान डालते हैं। मैं SQL सर्वर और T-SQL का उपयोग कर रहा हूं और SCOPE_IDENTITY () का उपयोग करने की कोशिश की है, लेकिन यह काम नहीं करता है क्योंकि तालिका में झूठी या बंद करने के लिए INSERT_IDENTITY है।

मैं वास्तव में सिर्फ एक नई पंक्ति सम्मिलित करने में सक्षम होने के लिए एक डमी मूल्य नहीं डालना चाहूंगा। धन्यवाद!


1
स्पष्ट करने के लिए: आपका प्रश्न है "एक एकल पहचान कॉलम के साथ SQL सर्वर तालिका में पंक्तियाँ कैसे डालें"?
gbn

हां, आप सही हैं, स्पष्ट करने के लिए धन्यवाद
फिल

2
यहां उतरने वाले लोगों के लिए, यह पहले पूछा गया है और सही उत्तर यहां है: stackoverflow.com/questions/850327/…
BJury 6'13

जवाबों:


140

यदि आपके पास एक कॉलम है जो एक पहचान है, तो बस यही करें

INSERT MyTable DEFAULT VALUES;  --allows no column list. The default will be the IDENTITY
SELECT SCOPE_IDENTITY();

यदि आपके पास पहचान नहीं है, तो क्या आप इसे सेट कर सकते हैं? यह सबसे अच्छा तरीका है .. और ऊपर SQL का उपयोग करें।

यदि नहीं, तो आप एक नई पंक्ति सम्मिलित करना चाहते हैं

INSERT MyTable (admidid)
OUTPUT INSERTED.admidid --returns result to caller
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable

टिप्पणियाँ:

  • उच्च भार के तहत MAX समाधान डुप्लिकेट के साथ विफल हो सकता है
  • तथ्य के बाद SCOPE_IDENTITY पहले नहीं है
  • SCOPE_IDENTITY केवल एक पहचान कॉलम के साथ काम करती है। IDENT_CURRENT का उपयोग करके किसी भी मूर्खता को हटाएं
  • आउटपुट क्लोक MAX समाधान के लिए SCOPE_IDENTITY को प्रतिस्थापित करता है

1

आपको अपने चयन विवरण में IDENTITY_INSERT को जोड़ना होगा:

SET IDENTITY_INSERT MyTable ON

INSERT INTO MyTable
(AdminCol)

SELECT AdminColValue

 FROM Tableb

जब आप कर लें, तो सुनिश्चित करें कि आप को याद है

SET IDENTITY_INSERT MyTable OFF

यह इस प्रकार से बोल से काम करता है का अच्छा वर्णन है: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx


क्या मैं इसे इस तरह से करने वाला हूं: INSERT INTO एडमिनिस्ट्रेटर (SCOPE_IDENTITY ()) SET IDENTITY_INSERT एडमिनिस्ट्रेटर SET IDENTITY_INSERT एडमिनिस्ट्रेटर ऑफ पर सेट करें?
फिल

हाँ। बस आपको इतना ही करना है। पर सेट करें, अपना कोड लिखें, अंत में सेट करें।
डाटाविटर

मुझे नहीं लगता कि यह सही उत्तर है। यदि यह एक पहचान स्तंभ है, तो आपको इसमें मान नहीं जोड़ने चाहिए। स्वीकृत उत्तर सही उत्तर है।
मम्म

0

@Phil: क्या आपका मतलब यह नहीं है कि आपकी तालिका में दो (2) कॉलम, ऑटोक्रेसी पीके कॉलम और एक व्यवस्थापक नाम है? यदि इसमें केवल एक कॉलम है जहाँ AdminName जाता है, तो AdminName PK है और आप निश्चित रूप से एक स्ट्रिंग को इंगित नहीं कर सकते। क्या व्यावसायिक नियम आपको पूरी तरह से योग्य विंडोज उपयोगकर्ता नाम प्राथमिक कुंजी बनाने की उम्मीद करते हैं? यह व्यवहार्य होगा और समझ में आता है, क्योंकि तब आपको AdminName कॉलम पर एक वैकल्पिक अद्वितीय सूचकांक की आवश्यकता नहीं होगी।

लेकिन अगर आपकी तालिका में दो कॉलम हैं, तो एक नहीं:

SQLServer में autoincrement तालिका / स्तंभ परिभाषा का हिस्सा है। आप स्तंभ को पूर्णांक के रूप में परिभाषित करते हैं और फिर इसे एक पहचान स्तंभ भी बनाते हैं, वेतन वृद्धि को निर्दिष्ट करते हुए, आमतौर पर 1, लेकिन यह 2 या 5 या 10 या जो भी हो सकता है। एक पंक्ति सम्मिलित करने के लिए, आप बस दूसरे कॉलम (मानों) को डालें और पीके कॉलम के साथ कुछ भी न करें:

insert into T
(foo)   -- column(s) list
values('bar') -- values list

आपकी संग्रहीत खरीद जो सम्मिलित करता है वह SCOPE_IDENTITY को RURURN मान बना सकता है या SCOPE_IDENTITY ग्राहक को वापस OUT पैरामीटर के रूप में पारित किया जा सकता है।

पीएस SCOPE_IDENTITY () मौजूदा दायरे में सबसे हाल ही में उत्पन्न स्वत: संचित पहचान मूल्य लौटाता है; यह अगले पहचान मूल्य को उत्पन्न नहीं करता है।

संपादित करें:

संभवतः, आपकी व्यवस्थापक तालिका में व्यवस्थापकों का एक समूह है। लेकिन अगर इसमें पूर्णांक प्राथमिक कुंजी कॉलम के अलावा कोई भी कॉलम नहीं है, तो प्रशासकों की पहचान करने का कोई तरीका नहीं है; केवल एक चीज जो आप कर सकते हैं, वह है उन्हें एक दूसरे से अलग करना। यह आपको बहुत दूर नहीं मिलता है। लेकिन अगर आपकी प्रशासक तालिका में निम्नलिखित संरचनाएं थीं:

ID   INTEGER PRIMARY KEY AUTOINCREMENT
windowsusername   varchar(50)  (unique index)

या

windowsusername varchar(50) primary key

आप अन्य तालिकाओं से व्यवस्थापक की तालिका को संदर्भित करने में सक्षम होंगे, और विदेशी कुंजी MEANINGFUL होगी। और यह ठीक है कि एक एकल पूर्णांक स्तंभ से मिलकर तालिका में क्या कमी है - अर्थ।

दो कॉलम होने के बाद, आप एक संग्रहीत कार्यविधि कर सकते हैं:

insert into Administrators
(windowsusername)
values('mydomain\someusername');
return SCOPE_IDENTITY();

और आपका क्लाइंट-प्रोग्राम एक लौटाए गए मान के रूप में वापस आ जाएगा जो स्वत: प्राप्त आईडी था जिसे ऑटोगेनरेटेड और नव सम्मिलित पंक्ति में सौंपा गया था। यह दृष्टिकोण सामान्य अभ्यास है, और मैं यह कहना चाहूंगा कि इसे "सर्वोत्तम अभ्यास" माना जाता है।

पुनश्च आप उल्लेख करते हैं कि आपको नहीं पता था कि "मूल्य डालने के लिए कैसे" यदि आपके पास "डालने के लिए कुछ भी नहीं था"। वहाँ एक विरोधाभास है। अगर आपके पास डालने के लिए कुछ नहीं है, तो क्यों डालें? यदि आप ग्राहक के बारे में बिल्कुल कुछ नहीं जानते हैं, तो आप एक नया ग्राहक रिकॉर्ड क्यों बनाएंगे? उनका नाम नहीं, उनका शहर, उनका फोन नंबर, कुछ नहीं?


2
मेरी तालिका में एक कॉलम, adminId है, जो कि एक वृद्धिशील इंट वैल्यू है
फिल

यह सबसे अजीब डिजाइन है जिसे मैंने कभी देखा है, और मैं 20 वर्षों से व्यवसाय में हूं और अपने दिन में कुछ अजीब चीजें देखी हैं। तो आपका सवाल यह है कि, आप एक तालिका में कैसे सम्मिलित होते हैं जिसमें केवल एक प्राथमिक कुंजी कॉलम होता है जिसे एक ऑटोइन्क्रिमेंटिंग पहचान कॉलम के रूप में परिभाषित किया जाता है, जब तालिका में वह पीके कॉलम और केवल वह पीके कॉलम, कोई अन्य कॉलम नहीं होता है ..
टिम

तो नीचे क्या है? कहीं एक तथ्यात्मक त्रुटि या डिजाइन की योग्यता की कमी के बारे में एक राय व्यक्त करने के लिए?
टिम

1
बस DB- डिजाइन के पीछे तर्क स्पष्ट करने के लिए। हमारे पास एक तालिका में उपयोगकर्ता हैं। यदि उपयोगकर्ताओं और प्रशासकों के बीच संबंध है; उन्हें प्रवेश के रूप में माना जाता है। वास्तविक अद्वितीय आईडी की तुलना में व्यवस्थापक-तालिका में रखने के लिए अधिक कुछ नहीं है। "वास्तविक" डेटा उपयोगकर्ता-तालिका और है-संबंध (टाइमस्टैम्प के साथ और जो आदि प्रदान किया गया है) में है।
फिल

1
@Phil: तो आप एक साधारण बूलियन / बिट कॉलम क्या कर सकते हैं यह व्यक्त करने के लिए एक टेबल और एक विदेशी कुंजी संबंध का उपयोग कर रहे हैं। आप अपनी तालिका में इस तरह के एक छोटे से कॉलम को जोड़ने में सक्षम नहीं हो सकते हैं और कुछ वर्कअराउंड के साथ आना होगा। But an autoincrementing integer whose autoincrementation must be disabled is a poor solution.आप सभी की जरूरत है एक समानांतर तालिका है जिसमें उपयोगकर्ता तालिका के लिए एक-से-एक संबंध है और उस तालिका में आप थोड़ा स्तंभ बनाते हैं। जब वह कॉलम सत्य होता है, तो इसका अर्थ है कि उपयोगकर्ता के पास व्यवस्थापक है स्वच्छ। स्टैंडर्ड। डिज़ाइन।
टिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.