13

我知道以下查询将从链接服务器中提取结果集:

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工作原理的问题。SELECTINSERT

我很感激任何帮助。

4

3 回答 3

10

不确定您尝试使用 INSERT 完成什么。

正确的语法(如果你想在远程服务器上插入)应该是

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

选择只会延迟您的插入检索选择查询返回的内容(无济于事),而不会给您额外的信息。此外,使用 openquery,您可以使用这种更正确的语法进行插入:

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

但是,如果您尝试将 select 检索到的值插入 LOCAL 服务器,则语法应该是:

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;

就足够了

于 2013-03-07T20:59:00.033 回答
4

在 SELECT 将返回记录的情况下,INSERT 不会返回结果集,但受影响的记录数除外。这可以通过使用 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)

至于从 INSERT 返回的记录,实现这一点的唯一方法是使用 OUTPUT 子句。客户端机器将无权访问 OUTPUT INSERTED 行,因此无法返回这些行。如果您尝试运行以下命令,您将收到错误消息:

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'
于 2013-03-07T00:14:12.660 回答
1

当您用于OPENQUERY执行INSERT时,它将执行第SELECT一个并丢弃结果。它使用结果集中的列元数据来确定如何发送INSERT命令。因此,您应该始终添加where 1=0SELECT.

从 SQL Server 到 MySQL,正确的语法是:

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

如果您在 MySQL 端激活常规查询日志,您将看到来自 SQL Server 的这些命令:

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 服务器将返回所有行。

于 2016-07-07T17:13:44.077 回答