0

我正在修改一些tcl代码,作者在代码中定义了sql语句。

我没有包含数据库连接代码或包需要 tclodbc 语句,但这实际上是我的测试用例的全部流程。

set query "alter table dbo.customer add constraint customer_pk primary key (c_custkey) with (maxdop=$maxdop)"
set maxdop 2

    if {[catch {db $query} err] } {
        puts "SQL ERROR"
        puts [format "ERROR is ===\n%s\n===" $err]
        }

但是我想让它更通用一点,并从文件中读取 sql。(这样我可以在不编辑程序的情况下试验 SQL)

所以我尝试了:

set silly_id [open silly.sql" r]
set sql_in   [gets $silly.sql]  

    if {[catch {db $sql_in} err] } {
        puts "SQL ERROR"
        puts [format "ERROR is ===\n%s\n===" $err]
    }

我已经尝试了几乎所有我能想象的 eval 和 subst 组合,但仍然无法让它工作。

4

2 回答 2

2

您正在寻找的代码是这样的:

# Correct pattern for reading from a file
set silly_id [open "silly.sql" r]
set sql_in   [read $silly_id]
close $silly_id

# Do substitutions in the SQL before evaluation
if {[catch {db [subst $sql_in]} err] } {
    puts "SQL ERROR"
    puts [format "ERROR is ===\n%s\n===" $err]
}

可是等等!

该代码有一个问题,因为它非常容易受到值问题的影响$maxdop(例如,如果它具有意外值,因为它来自不受信任的用户)。通常,您应该改用参数化查询。这对于一个ALTER TABLE(你不应该真正使用来自用户的任何信息)并不太重要,但是对于, SELECTUPDATE你需要非常小心。正确获取参数化语句要容易得多;TclODBC 也支持它们,您可以从文档中的这个示例中看到:INSERTDROP

% db statement s "从 id=132 的文章中选择全名"
s
%s
{全名132}
% db statement s2 "从 id1=? 的文章中选择全名?" 整数
s2
% s2 132
{全名132}
于 2012-04-23T19:02:11.100 回答
0

看起来你真的只是在问如何在 TCL 中打开和读取文件,对吧?您似乎使 SQL 部分工作正常。如果是这样,就这么简单(取自这里

     set fp [open "somefile" r]
     set file_data [read $fp]
     close $fp
于 2012-04-23T16:15:47.047 回答