2

我已经搜索过,但似乎找不到我正在寻找的东西。我在 Oracle 中运行 PL/SQL 脚本,并尝试使用 MySQL ODBC 5.2 Unicode 驱动程序通过数据库链接将记录插入 MySQL 中的表中。

该链接工作正常,我可以使用它在 Oracle 中进行复杂的查询,并对那里的记录进行各种插入和更新。

它失败的地方是尝试将记录插入到具有位(1)类型列的 MySQL 表中。

它基本上是一个用于循环的游标,插入语句看起来像:

INSERT INTO "app_user"@mobileapi (USERNAME, VERSION, ACCOUNT_EXPIRED, ACCOUNT_LOCKED, PASSWD, PASSWORD_EXPIRED)
VALUES  (CU_rec.USERNAME, CU_rec.VERSION, CU_rec.ACCOUNT_EXPIRED, CU_rec.ACCOUNT_LOCKED, CU_rec.PASSWD, CU_rec.PASSWORD_EXPIRED)

一些目标列,如ACCOUNT_EXPIREDACCOUNT_LOCKED等是bit(1)MySQL 中的列。鉴于我可以将游标中的数据类型转换为CU_rec我在 Oracle 中想要的几乎任何东西,我怎样才能将它们插入到目标中?我已经尝试了我能想到的一切,我只是不断得到:

错误报告:

ORA-28500: connection from ORACLE to a non-Oracle system returned this message:
[MySQL][ODBC 5.2(w) Driver][mysqld-5.6.10]Data too long for column 'ACCOUNT_EXPIRED' at row 1 {HY000,NativeErr = 1406}
ORA-02063: preceding 2 lines from MOBILEAPI
ORA-06512: at line 44
28500. 00000 -  "connection from ORACLE to a non-Oracle system returned this message:"
*Cause:    The cause is explained in the forwarded message.
*Action:   See the non-Oracle system's documentation of the forwarded
           message.

任何帮助都将不胜感激。

4

2 回答 2

0

哈!我找到了解决方案。把它放在这里以防它帮助别人。它不漂亮,但它有效。

我使用了旧的 EXECUTE IMMEDIATE 技巧。

基本上,我创建了一个变量sql_stmt varchar2(4000)并编写了如下代码:

sql_stmt := 'insert into "app_user"@mobileapi (USERNAME, VERSION, ACCOUNT_EXPIRED, ACCOUNT_LOCKED, CIPHER_PASSPHRASE, ENABLED, PASSWD, PASSWORD_EXPIRED) 
values ('''||CU_rec.USERNAME||'','||CU_rec.VERSION||', '||CU_rec.ACCOUNT_EXPIRED||', '||CU_rec.ACCOUNT_LOCKED||', '''||CU_rec.CIPHER_PASSPHRASE||''', '|| 
           CU_rec.ENABLED||', '''||CU_rec.PASSWD||''', '||CU_rec.PASSWORD_EXPIRED||')';
EXECUTE IMMEDIATE sql_stmt;

无论如何都是这样的(引号可能不对齐,因为我从实际代码中破解了一点)。查看 sql_stmt 的内容,我得到:

insert into "app_user"@mobileapi (USERNAME, VERSION, ACCOUNT_EXPIRED, ACCOUNT_LOCKED, CIPHER_PASSPHRASE, ENABLED, PASSWD,PASSWORD_EXPIRED) 
values ('user@email.com', 0, 0, 0, 'asdfastrwaebawavgansdhnsgjsjsh', 1, 'awercbcakwjerhcawuerawieubkahbewvkruh', 0)

EXECUTE IMMEDIATE 完成,并检查目标表,值在那里。

可能是一个糟糕的解决方案,但总比没有好。

于 2013-05-27T23:03:02.773 回答
0

您的问题是 Oracle通过 ODBC进行的默认数据类型转换;根据他们自己的文档,他们将 SQL_BINARY 转换为原始文件。尽管不直接相关,但Oracle 在 SQL Developer 中对 MySQL 和 Oracle 的比较也暗示了从 MySQL 位到 Oracle raw 的自动转换这一事实。

非常令人困惑的是,MySQL 的文档表明一个位被转换为一个 SQL_BIT 或一个 SQL_CHAR,这意味着它可能在另一个方向上工作1

根据Microsoft 的 ODBC 文档,理论上,您应该能够使用该CONVERT()函数将其转换为字符,理论上应该可以由 MySQL 翻译。

insert into some_table@some_db (bit_col)
values( {fn convert(some_col, SQL_CHAR)} );

失败还有另外几个选项,但这确实取决于您尝试从 Oracle 插入 MySQL 数据库的内容以及 Oracle 中的数据类型。例如,您可以使用 OracleCAST()函数在数据类型之间进行转换。例如,以下将整数转换为二进制双精度。

select cast(1 as binary_double) from dual

不幸的是,您不能将整数转换为原始数据,只能转换为字符或 rowid,因此为了转换为原始数据,您必须执行以下操作:

select cast(to_char(1) as raw(1)) from dual

我不知道 MySQL 是否会接受这个,但通过一些测试你应该能够解决它。

1. 为清楚起见,我从未尝试过任何一个方向。

于 2013-05-27T21:50:32.060 回答