简体   繁体   English

INSERT INTO 的第一列通过链接服务器 MS SQL -> MySQL 始终为空字符串

[英]First column of INSERT INTO over linked server MS SQL -> MySQL always empty string

I have a MS SQL 2005 server with a linked server connection to a MySQL 5.1.46 server, using the ODBC Connector 5.1.8 driver.我有一个 MS SQL 2005 服务器,它使用 ODBC 连接器 5.1.8 驱动程序通过链接服务器连接到 MySQL 5.1.46 服务器。

I want to, from a MS SQL job, truncate and then rebuild a remote MySQL table based on the records contained in an identically-structured local MS SQL table.我想从 MS SQL 作业中截断,然后根据结构相同的本地 MS SQL 表中包含的记录重建远程 MySQL 表。

Key_ID  varchar(10)  NOT NULL  Primary
FieldA  varchar(64)
FieldB  text

Key_ID   FieldA   FieldB
======   ======   ======
ID1      A        A
ID2      B        B
ID3      C        C

The problem is, when I run the following query from MS SQL, I get an error saying "Duplicate entry '' for key 'PRIMARY'."问题是,当我从 MS SQL 运行以下查询时,我收到一条错误消息,提示“键 'PRIMARY' 的重复条目 ''。” If I remove the primary key, it will add all the records but the remote MySQL Key_ID field always returns an empty string, even though no records in the local table are NULL or empty strings.如果我删除主键,它将添加所有记录,但远程 MySQL Key_ID 字段始终返回空字符串,即使本地表中没有记录为 NULL 或空字符串。

EXECUTE ('DELETE FROM DB1.Table1') AT REMOTESERVER

INSERT INTO
 OPENQUERY( REMOTESERVER, 'SELECT * FROM DB1.Table1' )
SELECT
 Key_ID,
 FieldA,
 FieldB
FROM
 Table1

returns返回

Key_ID   FieldA   FieldB
======   ======   ======
         A        A
         B        B
         C        C

This makes absolutely no sense.这完全没有意义。

If I add a dummy field to the beginning of the remote MySQL table, then modify my query to insert a literal value or NULL into it, that field always comes up as an empty string and my Key_ID field returns as expected.如果我在远程 MySQL 表的开头添加一个虚拟字段,然后修改我的查询以在其中插入一个文字值或 NULL,该字段总是作为一个空字符串出现,我的 Key_ID 字段按预期返回。

Dummy   varchar(64)
Key_ID  varchar(10)  NOT NULL  Primary
FieldA  varchar(64)
FieldB  text

and

EXECUTE ('DELETE FROM DB1.Table1') AT REMOTESERVER

INSERT INTO
 OPENQUERY( REMOTESERVER, 'SELECT * FROM DB1.Table1' )
SELECT
 'srsly wtf?',
 Key_ID,
 FieldA,
 FieldB
FROM
 Table1

returns返回

Dummy   Key_ID   FieldA   FieldB
=====   ======   ======   ======
        ID1      A        A
        ID2      B        B
        ID3      C        C

As far as I can tell, the leftmost first column is always returning an empty string.据我所知,最左边的第一列总是返回一个空字符串。 Does anybody have any possible idea why, or can give me ideas for workarounds that don't involve a dummy field that serves no purpose other than acting as a buffer field?有没有人有任何可能的想法为什么,或者可以给我一些不涉及虚拟字段的解决方法的想法,该虚拟字段除了充当缓冲字段之外没有任何用途?

UPDATE: I enabled the debug logging on the ODBC driver, and found that it translates my SQL statement into:更新:我在 ODBC 驱动程序上启用了调试日志记录,发现它将我的 SQL 语句转换为:

INSERT INTO `DB1`.`Table1` (`Key_ID`, `FieldA`, `FieldB`) VALUES ( DEFAULT, 'A', 'A' )

If I add the dummy field, it runs:如果我添加虚拟字段,它会运行:

INSERT INTO `DB1`.`Table1` (`Dummy`, `Key_ID`, `FieldA`, `FieldB`) VALUES ( DEFAULT, 'ID1', 'A', 'A' )

I have no idea what to think now, other than that the driver assumes that the first supplied field is always an incrementing primary key?我不知道现在该想什么,除了驱动程序假定第一个提供的字段始终是递增的主键?

I found the answer to my own question.我找到了我自己问题的答案。

The problem lies in that FieldB is a text datatype.问题在于 FieldB 是一种文本数据类型。

I changed the MySQL Table1.FieldB from text to varchar, and everything started working perfectly as expected.我将 MySQL Table1.FieldB 从 text 更改为 varchar,一切都开始按预期完美运行。 (Of course, I had to potentially truncate the data in my original MySQL table, but in my circumstance that isn't a huge deal.) (当然,我可能不得不截断原始 MySQL 表中的数据,但在我的情况下,这不是什么大问题。)

The baffling part is that even before I redefined the datatype, the FieldB field still INSERTed correctly, and gave no indication that its existence was the problem.令人困惑的部分是,即使在我重新定义数据类型之前,FieldB 字段仍然正确插入,并且没有表明它的存在是问题所在。

I just encountered the same issue and I think the problem is related with the MySQL Text type as the last column of the table.我刚刚遇到了同样的问题,我认为问题与作为表的最后一列的 MySQL Text 类型有关。

Let's say I have the following table:假设我有下表:

CREATE TABLE `Test` (
  `id` int(11) NOT NULL DEFAULT '0',
  `field1` int(11) DEFAULT NULL,
  `field2` varchar(16) DEFAULT NULL,
  `field3` varchar(16) DEFAULT NULL,
  `field4` varchar(1) DEFAULT NULL,
  `field5` varchar(200) DEFAULT NULL,
  `field6` text,
  `field7` text,
  `field8` text,
  `field9` text,
  `field10` text,
  `field11` text,
  `field12` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

And on SQL Server I execute the following (test and db.dbo.test has the same schema):在 SQL Server 上,我执行以下操作(test 和 db.dbo.test 具有相同的架构):

INSERT OPENQUERY (MYSQL_LINK, 'SELECT * FROM test) SELECT * FROM db.dbo.test

then id, field1 to field5 will become NULL and field6 to field 12 will have the right data.然后 id, field1 到 field5 将变为 NULL 并且 field6 到 field 12 将有正确的数据。

If I do the following:如果我执行以下操作:

INSERT OPENQUERY (MYSQL_LINK, 'SELECT id, field1, field2, field3, field4, field5 FROM test) SELECT id, field1, field2, field3, field4, field5 FROM db.dbo.test

Then the id and field1 to field5 will have the correct data.然后 id 和 field1 到 field5 将有正确的数据。

If I purportedly insert the the field6 too, the id will become NULL.如果我据称也插入了 field6,则 id 将变为 NULL。 If I insert the field7, then field2 will become NULL too and so on.如果我插入 field7,那么 field2 也会变成 NULL,依此类推。

I've been using OPENQUERY to transfer dozens of MSSQL table to MySQL without any issue.我一直在使用 OPENQUERY 将数十个 MSSQL 表传输到 MySQL,没有任何问题。 After reviewing the other tables schemas I noticed that none of them ended with a TEXT type in MySQL.在查看其他表模式后,我注意到它们都没有以 MySQL 中的 TEXT 类型结尾。 So I made a little change on the MySQL schema by adding an integer column at the end and voilá!所以我通过在末尾添加一个整数列对 MySQL 模式进行了一些更改,瞧! It worked!有效!

CREATE TABLE `Test_new` (
  `id` int(11) NOT NULL DEFAULT '0',
  `field1` int(11) DEFAULT NULL,
  `field2` varchar(16) DEFAULT NULL,
  `field3` varchar(16) DEFAULT NULL,
  `field4` varchar(1) DEFAULT NULL,
  `field5` varchar(200) DEFAULT NULL,
  `field6` text,
  `field7` text,
  `field8` text,
  `field9` text,
  `field10` text,
  `field11` text,
  `field12` text,
  `field13` int(11) NOT NULL DEFAULT '0',
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

And the query:和查询:

INSERT OPENQUERY (MYSQL_LINK, 'SELECT * FROM test_new') SELECT *,0 FROM db.dbo.test

I don't know where I should address this issue.我不知道我应该在哪里解决这个问题。 Is a MSSQL OPENQUERY bug or a MySQL Connector bug?是 MSSQL OPENQUERY 错误还是 MySQL 连接器错误? I don't know.我不知道。 But I hope my finding will help you guys save some time on debugging.但我希望我的发现能帮助你们节省一些调试时间。

What happens if you change the如果你改变了会发生什么

OPENQUERY( REMOTESERVER, 'SELECT * FROM DB1.Table1' ) 

Statement to声明

OPENQUERY( REMOTESERVER, 'SELECT Key_ID, FieldA, FieldB FROM DB1.Table1' ) 
INSERT INTO `DB1`.`Table1` ( `FieldB`,`Dummy`, `Key_ID`, `FieldA`) VALUES ('A', DEFAULT, 'ID1', 'A' )

如果将文本列移到顶部,则问题已解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM