我知道以下查询将从链接服务器下拉结果集:
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
如何运作的问题。
我感谢任何帮助。
答案 0 :(得分:10)
不确定您尝试使用INSERT完成的任务。
正确的语法(如果要在REMOTE服务器上插入)应为
INSERT into openquery(MyServer, 'dbo.event_cast') values ('','')
select只会延迟你的插入检索选择查询返回的内容(无效),而不会给你额外的信息。此外,使用openquery,您可以使用此语法,更正确的插入:
INSERT into myserver.mydatabase.dbo.event_Cast values('','')
但是,如果您尝试插入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;
就足够了
答案 1 :(得分: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'
答案 2 :(得分:1)
当您使用OPENQUERY
执行INSERT
时,它会首先执行SELECT
并丢弃结果。它使用结果集中的列元数据来确定如何发送INSERT
命令。因此,您应始终将where 1=0
添加到SELECT
的末尾。
从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')
所以你可以看到select正在执行两次。如果没有where 1=0
,MySQL服务器将返回所有行。