Как OPENQUERY отличается для 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')
если первое, то это очень неэффективно. Должен ли я ограничить возвращаемый результирующий набор и будет ли этот эффект my INSERT
?
это в основном вопрос о том, как OPENQUERY
строительство, когда дело доходит до SELECT
и INSERT
.
Я ценю любую помощь.
3 ответов
не уверен, что вы пытаетесь выполнить с помощью вставки.
правильный синтаксис (если вы хотите вставить на удаленный сервер) должен быть
INSERT into openquery(MyServer, 'dbo.event_cast') values ('','')
выбор только задерживает вашу вставку, извлекая то, что когда-либо возвращает запрос select (безрезультатно), не давая вам дополнительной информации. Кроме того, с openquery вы можете использовать этот синтаксис, более правильный, для вставки:
INSERT into myserver.mydatabase.dbo.event_Cast values('','')
но, если вы пытаетесь вставить в локальный сервер значения, полученные синтаксис select должен быть:
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;
хватит
Если SELECT вернет записи, вставка не вернет результирующий набор, за исключением количества затронутых записей. Это можно подавить с помощью SET NOCOUNT ON; однако я не уверен, будет ли подавление ссылаться на видимость или количество строк на самом деле.
INSERT INTO OPENQUERY(MYSERVER, 'SELECT [Drive_Letter] ,[MBFree],[Server] FROM [Blah].[dbo].[SQL_Drives]')
SELECT 'X', 2, 'MyServer'
(1 row(s) affected)
Что касается записей, возвращаемых из вставки, единственный способ сделать это-использовать предложение OUTPUT. Клиентский компьютер не будет иметь доступа к выходным вставленным строкам, поэтому они не могут быть возвращены. При попытке выполнить следующее, Вы получите сообщение об ошибке:
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'
при использовании OPENQUERY
для выполнения INSERT
, он будет выполнять SELECT
сначала и выбросить результаты. Он использует метаданные столбца из результирующего набора, чтобы определить, как направить . По этой причине вы всегда должны добавить where 1=0
до конца SELECT
.
от SQL Server до MySQL правильный синтаксис:
insert into openquery(MYSQLDEV, 'select * from insert_test where 1=0') values ('test');
если вы активируете общий журнал запросов на стороне MySQL, вы увидите эти команды, поступающие из SQL Сервер:
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.