我正在修改一些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组合 仍然无法让它工作。
答案 0 :(得分: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
(您不应该真正使用用户的任何信息)而言SELECT
,UPDATE
,INSERT
和{{ 1}}你需要非常小心。获得参数化语句要容易得多; TclODBC也支持它们,正如您在documentation:
% db statement s "select fullname from article where id=132" s % s {FullName132} % db statement s2 "select fullname from article where id1=?" INTEGER s2 % s2 132 {FullName132}
答案 1 :(得分:0)
看起来你真的只是问如何在TCL中打开和读取文件,对吧?你似乎让SQL部分正常工作。如果是这样,它就像这样简单(取自here)
set fp [open "somefile" r]
set file_data [read $fp]
close $fp