3

几年来,我们一直在使用 tclodbc 包对 MS SQL Server 运行查询。现在我们必须切换到 x64 进程并且 tclodbc 不会加载,因为没有 x64 版本。

我们开始寻找替代方案并尝试了 tdbc,但我们遇到了作为参数传递的字符字段的问题。我创建了一个包含 2 个整数列和 2 个 varchar 列(50 和 100 长)的测试表。

我正在尝试插入记录并发生以下情况: 1. 如果我插入仅提供 2 个整数参数的记录,一切正常 - 插入 5 条记录(请参见下面的代码)。2. 如果我插入仅提供 1 个字符参数的记录 1 条记录被插入,然后脚本失败并出现以下错误:“[Microsoft][ODBC Driver 11 for SQL Server]String data, right truncation” 3. 如果我传递了两个字符参数或整数参数和字符参数然后没有插入任何内容 - 我得到与上面相同的错误。

我没有测试任何其他数据类型,但看起来字符参数有问题(我也尝试了 nvarchar 和 char 类型列)。

这是我的代码:

package require tdbc::odbc
set con "Driver=\{ODBC Driver 11 for SQL Server\};server=server;database=database;Intergrated Security=True;Trusted_Connection=Yes"
tdbc::odbc::connection create db $con

set insert_cmd [db prepare {INSERT INTO dbo.testing_tdbc (f50,f100) VALUES(:f50,:f100) } ]
$insert_cmd paramtype f50 char 50
$insert_cmd paramtype f100 char 100

foreach fint [list 1 2 3 4 5] {
    set fi1 $fint
    set fi2 [expr {$fi1*2}]
    set f50 "${fi2}_${fi1}"
    set f100 $f50

    $insert_cmd execute
}

$insert_cmd close
db close

我对 SQL Server 的 ODBC Driver 13 进行了同样的尝试——结果都相同。

4

1 回答 1

0

[Microsoft][ODBC Driver 11 for SQL Server]字符串数据,右截断

您可能知道,此错误是由于插入的字符串比声明的列精度长。

根据tdbc::statement manual,语法为$stmt paramtype

$stmt paramtype ?direction? type ?precision? ?scale?

所以我不太确定你在这里传递f50的意思direction(应该是以下之一:in, inout, out。我认为你可以省略$stmt paramtype调用并直接$insert_cmd使用例如$stmt execute ?dict?

set insert_cmd [db prepare {INSERT INTO dbo.testing_tdbc (f50,f100) VALUES(:f50,:f100) } ]

foreach fint {1 2 3 4 5} {
   set value [expr {$fint*2}]_$fint
   set bindings [dict create f50 $value f100 $value]
   $insert_cmd execute $bindings
}

$insert_cmd close
db close
于 2018-03-04T10:52:57.043 回答