2013-03-04 4 views
13

मुझे पता है कि निम्न क्वेरी परिणाम किसी लिंक किए गए सर्वर से सेट नीचे खींच जाएगा: जब यह डालने की बात आती हैOPLECTQUERY SELECT और INSERT के लिए भिन्न कैसे है?

SELECT * FROM openquery(DEVMYSQL, 
    'SELECT event_id, people_id, role_id, rank, last_updated FROM event_cast') 

बहरहाल, यह एक ही मामला है? क्या यह परिणाम सेट को खींच देगा या क्या इसे कॉलम जानकारी मिल जाएगी?

INSERT INTO openquery(DEVMYSQL, 
    'SELECT event_id, people_id, role_id, rank, last_updated FROM event_cast') 

यदि पूर्व, तो यह बहुत अक्षम है। क्या मुझे परिणाम सेट को सीमित करना चाहिए और क्या यह मेरा INSERT प्रभावित करेगा?

यह मूल रूप से OPENQUERY काम करता है जब SELECT और INSERT पर आता है।

मैं किसी भी मदद की सराहना करता हूं।

उत्तर

10

सुनिश्चित नहीं हैं कि क्या आपके सम्मिलित करें के साथ पूरा करने के लिए प्रयास करें।

सही सिंटैक्स (यदि आप दूरस्थ सर्वर पर सम्मिलित करना चाहते हैं) होना चाहिए

INSERT into openquery(MyServer, 'dbo.event_cast') values ('','') 

चयन केवल अपने डालने पुन: प्राप्त करने में देर कभी क्या चयन क्वेरी (कोई लाभ नहीं हुआ) आप अतिरिक्त जानकारी दिए बिना । होना चाहिए

INSERT into myserver.mydatabase.dbo.event_Cast values('','') 

लेकिन, यदि आप वाक्य रचना का चयन मूल्यों द्वारा प्राप्त स्थानीय सर्वर में डालने के लिए कोशिश कर रहे हैं:: इसके अलावा, OPENQUERY साथ आप इस वाक्य रचना, अधिक सही, सम्मिलित करने के लिए इस्तेमाल कर सकते हैं

INSERT into dbo.my_localtable SELECT * FROM openquery(DEVMYSQL, 'SELECT event_id, people_id, role_id, rank, last_updated FROM event_cast') 

और हाँ, वाक्य मूल्यों को सम्मिलित करेगा, न केवल कॉलम जानकारी।

आप केवल मेज स्थानीय स्तर पर एक सरल

SELECT top 1 * into new_local_event_cast FROM openquery(DEVMYSQL, 'SELECT event_id, people_id, role_id, rank, last_updated FROM event_cast'); 
TRUNCATE TABLE new_local_event_cast; 

को दोहराने के लिए

+2

बस एफवाईआई: दूसरे उदाहरण में चार भाग नामकरण वाक्यविन्यास केवल तभी काम करता है जब लिंक किए गए सर्वर प्रकार को वितरित लेनदेन में नामांकित किया गया हो। (अधिकांश हैं, सिर्फ एक गोचा।) –

+0

अपनी पहली क्वेरी के साथ, आप कॉलम को किसी चयन के माध्यम से कॉलम निर्दिष्ट किए बिना डालने का निर्धारण कैसे कर रहे हैं? – Abs

+0

मैं पहचान डेटा या डिफ़ॉल्ट डेटा के साथ कॉलम को छोड़कर पूरी तरह से सम्मिलित करता हूं (अधिकांश बार मैं डिफ़ॉल्ट डेटा भी लिखता हूं)। आम तौर पर पूरे रिकॉर्डसेट को सम्मिलित करने के लिए तेज़ होता है क्योंकि यह इसे डेटा के एक हिस्से के रूप में लिखता है। ओपनक्वेरी मान लेता है कि कोल्स डालने वाले क्रम में हैं (सामान्य डालने के रूप में)। सच है: यदि आपको लगातार निरंतर कॉलों को निर्दिष्ट करने की आवश्यकता है, तो आपको चयन का उपयोग करने की आवश्यकता है, लेकिन प्रदर्शन की लागत पर – Zelloss

4

जहां चयन रिकॉर्ड वापस करेगा, आईएनएसईआरटी प्रभावित रिकॉर्ड की गिनती को छोड़कर परिणाम सेट वापस नहीं करेगा। इसे सेट एनओसीटीटी का उपयोग करके दबाया जा सकता है; हालांकि, मुझे यकीन नहीं है कि क्या दमन दृश्यता या पंक्ति गणना वास्तव में आ रहा है।

INSERT INTO OPENQUERY(MYSERVER, 'SELECT [Drive_Letter] ,[MBFree],[Server] FROM [Blah].[dbo].[SQL_Drives]') 
    SELECT 'X', 2, 'MyServer' 

(1 row(s) affected) 

रिकॉर्ड के लिए के रूप में एक आउटपुट खंड का उपयोग करने, सम्मिलित करें से लौटे जा रहा है कि ऐसा करने के लिए एक ही रास्ता है। क्लाइंट मशीन को आउटपुट पंक्तियों तक पहुंच नहीं होगी, इसलिए उन्हें वापस नहीं किया जा सकता है। आप निम्नलिखित चलाने का प्रयास करते हैं, तो आपको एक त्रुटि प्राप्त होगा:

INSERT INTO OPENQUERY(MYSERVER, 'SELECT [Drive_Letter] ,[MBFree],[Server] FROM [BLAH].[dbo].[SQL_Drives]') 
OUTPUT INSERTED.* 
SELECT 'X', 2, 'MyServer' 

Msg 405, Level 16, State 1, Line 1 
A remote table cannot be used as a DML target in a statement which includes an OUTPUT clause or a nested DML statement. 


-- EDIT RESULTS OF PROFILER ---------------------------  


-- Statements that occured on server called through OPENQUERY 
    exec sp_cursoropen @p1 output,N'SELECT [Drive_Letter] ,[MBFree],[Server] FROM [MyServer].[dbo].[SQL_Drives]',@p3 output,@p4 output,@p5 output 
    select @p1, @p3, @p4, @p5 

    exec sp_cursor 180150009,4,0,N'[MyServer].[dbo].[SQL_Drives]',@Drive_Letter='X',@MBFree=2,@Server='MyServer' 


--Statements that occured on client 
    INSERT INTO OPENQUERY(MyServer, 'SELECT [Drive_Letter] ,[MBFree],[Server] FROM [MyServer].[dbo].[SQL_Drives]') 
    SELECT 'X', 2, 'MyServer' 
+0

जब मैं 'INSERT' का संदर्भ देता हूं, तो मैं वास्तव में 'OPLECTQUERY' के भीतर 'SELECT' के बारे में बात कर रहा हूं। यह क्वेरी लिंक किए गए सर्वर पर निष्पादित की जाती है और फिर 'INSERT' को स्थानीय सर्वर पर निष्पादित किया जाएगा। हालांकि, क्या SQL सर्वर को एहसास होगा कि यह एक 'INSERT' है और इसलिए लिंक किए गए सर्वर से परिणाम सेट वापस नहीं लौटाएगा? – Abs

+0

मैंने बस एक ही बयान चलाया और प्रत्येक छोर पर प्रोफाइलर देखा। परिणाम ऊपर हैं, मुझे विश्वास है कि चयन केवल सर्वर पर होता है जिसे OPENQUERY द्वारा बुलाया जाता है और यह कि चयन किसी अन्य चीज़ की तुलना में सम्मिलित करने के लिए टेम्पलेट के रूप में अधिक कार्य करता है। – PseudoToad

1

पर्याप्त होगा जब आप OPENQUERY का उपयोग एक INSERT प्रदर्शन करने के लिए चाहते हैं, यह SELECT पहले प्रदर्शन और परिणाम फेंक होगा। यह INSERT कमांड को भेजने का तरीका निर्धारित करने के लिए परिणाम सेट से कॉलम मेटाडेटा का उपयोग करता है। इसी कारण से आपको हमेशा SELECT के अंत में जोड़ना चाहिए।

एसक्यूएल सर्वर से MySQL करने के लिए उचित सिंटैक्स है:

insert into openquery(MYSQLDEV, 'select * from insert_test where 1=0') values ('test'); 

आप MySQL तरफ सामान्य क्वेरी लॉग को सक्रिय करते हैं तो आप इन आदेशों एसक्यूएल सर्वर से आ रही देखेंगे:

SET NAMES utf8 
SET character_set_results = NULL 
SET SQL_AUTO_IS_NULL = 0 
set @@sql_select_limit=1 
select * from insert_test where 1=0 
select * from insert_test where 1=0 
INSERT INTO `database`.`insert_test`(`column`) VALUES ('test') 

तो आप देख सकते हैं कि चयन दो बार किया जा रहा है। where 1=0 के बिना, सभी पंक्तियों को MySQL सर्वर द्वारा वापस कर दिया जाएगा।

संबंधित मुद्दे