您的位置:首页 > 数据库

如何在一个脚本文件中超越OSQL的1000字符限制

2010-02-02 16:12 591 查看
[问题的提出]

在维护一个老的系统,用的是SQL2000。

需要向SE提交一个脚本文件来更新数据库。

SE要求:文件最好只有一个,不要弄好几个;双击就可以执行,不要打复杂的命令行。

[探讨]

一开始觉得这有何难,用个BAT/VBS调用OSQL执行一堆脚本就OK了。

一旦着手,发现不那么容易,OSQL的-Q参数不支持1000个字符以上的SQL语句。

如果是分语句执行到也算OK,最多就是多执行几次吧了。

但数据库中,有部分VIEW超大,CREATE VIEW单条语句本身就超过4K。

-i虽然可以支持理论上任意大小的文本,却需要多文件才能完成。

暗暗叫苦于之前已盲目答应SE的“非份”要求。

[解决]

再静下心来看,能不能让调用osql.exe的脚本文件中,osql的-i调用脚本自已呢?

-i所指向的输入文件到是无所谓,无论后缀,只要是合格的T-SQL,都能执行。

但如何让T-SQL与控制脚本熔于1个文件中?关键是如何可以分别将对方注释掉。

仔细的分析了各脚本语言后,发现*.js文件正好可以做到这件事。

主要的突破点在于*.js文件与*.sql的跨行注释方法完全一致。

而同时*.js却又有路径可以选择性的注释掉部分语句。

那就是条件编译。

JScript的相关说明如下:

Conditional compilation allows the use of new JScript language features without sacrificing compatibility with older versions that do not support the features.

Conditional compilation is activated by using the @cc_on statement, or using an @if or @set statement. Some typical uses for conditional compilation include using new features in JScript, embedding debugging support into a script, and tracing code execution.

Always place conditional compilation code in comments, so that hosts (like Netscape Navigator) that do not understand conditional compilation will ignore it. Here is an example.

/*@cc_on @*/
/*@if (@_jscript_version >= 4)
alert("JScript version 4 or better");
@else @*/
alert("You need a more recent script engine.");
/*@end @*/


This example uses special comment delimiters that are only used if conditional compilation is activated by the @cc_on statement. Scripting engines that do not support conditional compilation only see the message informing of the need for a new scripting engine.

模拟它写个如下的js文件,该文件既包含了运行SQL的控制语句,又含有需要运行的SQL语句。

有点象以前买到过的自带播放器的VCD光盘。

运用方法:拷贝下述代码存为后缀名为js的任意文件,双击即可运行。

/*@cc_on @*/
/*@set @myvar1=1 @*/
/*@if (@myvar1>=1)
//////// JScript Starts here
// Run a set of SQL use a individual js file

var WshShell=new ActiveXObject("WScript.Shell");
WshShell.Run("osql -S (local) -U sa -P -i /""+WScript.ScriptFullName+"/"", 1, true);
//////// JScript Ends here
@else @*/
-------- SQL Starts here
use [Northwind]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbTest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbTest]
GO

CREATE TABLE [dbo].[tbTest] (
[id] [int] NULL ,
[Name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[AnyWords] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO

-------- SQL Ends here
/*@end @*/


感觉比较有趣,特此记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: