【转】DB2 的命令行处理器和脚本编写

命令行处理器是 DB2 的接口,它最佳地体现了 DB2 的威力,以及 DB2 的简单性和通用性。作者通过例子对其进行了详细的论述。

0 评论:

Blair Adamache, DB2 Technology Development, IBM

关闭 [x]

Blair Adamache 是 IBM 多伦多实验室里的一名有 17 年工作经验的老员工。他拥有修辞学(Rhetoric)的硕士学位,但是承诺只将自己的能力应用于好的服务。Blair 当前的职责是管理 DB2 服务小组,这个小组负责确保客户能够继续享用数据库业内最好的软件支持。Blair 有多年的和用户打交道的经验,涉及营销、服务、开发和管理。他是"DB2 Fundamentals Certification for Dummies (Hungry Minds)"的技术编辑,"The Complete DB2 Reference (McGraw Hill)"的合著者之一,并且为 IBM DB2 开发者园地撰写过许多文章。因为技术问题而找 Blair 的最好方式就是发邮件至 comp.databases.ibm-db2。

2003 年 6 月 01 日

何时使用 DB2 命令行处理器

IBM DB2 命令行处理器听起来没什么特别之处,但实际上它是 DB2 的接口,它最佳地体现了DB2的威力,以及 DB2 的简单性和通用性。命令行并不可爱(实际上,Windows 上的 DB2 曾得到一个“强大但是不可爱”的名声。那是 DB2 在 NT 上初次发布的时候,当时还没有 ControlCenter 可用)。命令行使我们想起了 UNIX 上的 Telnet,还有 1981 年开始使用的 DOS 命令。但是,如果您的 SQL 命令够强大—— 或者您想通过输入一个快速命令来验证 DB2 的安装情况——那么命令行是理想的,而且通常比通过像 PowerBuilder 或者Access 这样的前端提交请求要来得快。CLP 是通往每一个 DB2 编程接口的直接路径。它使得任何可以程式化地调用的东西能够通过接口来调用——或者在一个简单的脚本(就像我们曾在 DOS 中编写过的 .BAT 文件)中调用。像 MVS 上的SPUFI、VM 上的 ISQL 以及 VSE 上的 SQLDBSU 这些类似的工具都十分耐用,这使得我们深信 CLP 必定可以使用很长一段时间。

本文将向您展示如何使用命令行处理器(简称 CLP)来为您带来好处。如果对某些工作原理还不够明了的话,可以参考手册(                 DB2 Command Reference),这个手册用一整章介绍 CLP 的使用。


回页首

验证安装情况和判定问题所在

当我第一次在 OS/2 上安装 DB2 时(在此一年前 DB2 已经可以在 NT 上使用了),我已经在很多其他的操作系统(DOS,VM,VSE,MVS™,AS/400®)上使用过 SQL Database 管理器了。成功地安装完之后,我开始阅读 about 信息,这时我被“cataloging nodes and databases(编目节点和数据库)”这件事给弄糊涂了。catalog 这个词与过去惹人喜爱的 SYSCAT 和 SYSIBM 目录相比有着动词化的意味。有时候,我会对着 DB2 大声埋怨:“我不想编目任何东西,我只是想通过运行一个SELECT语句来确保我正确地安装了DB2。”几个小时之后,我冷静下来,了解到只有创建了一个数据库之后 DB2 才会有数据库目录;您不需要在本地机器上将节点和数据库编目——只有在一个连接到服务器的客户机上时才需要编目。创建样本数据库非常容易——运行 db2sampl  就可以了。在验证安装情况时,命令行处理器 正是我所需要的工具,这时可以运行: DB2 SELECT COUNT(*) FROM SYSCAT.TABLES

在 UNIX 和 OS/2 上,您只需使用一个常见的操作系统提示符,并在任何 DB2 命令或者 SQL 语句前面加上"DB2" 。在 Windows 上,事情要麻烦一些,这在后面会解释,不过您可以通过输入 DB2CMD 来创建一个适合 DB2 命令、SQL 和 操作系统命令(例如 dir 和 ren)的提示符。您甚至可以混合使用 SQL、DB2 命令和操作系统参数,例如用 |more 来滚动屏幕,用大于号(>)来向文件输送内容: DB2 select * from employee>c:\\tmp\\emp.out |more

注意:对于那些对 DB2 和操作系统都有意义的符号,比如 Windows 上的大于号(>),操作系统会最先给予解释。SELECT * FROM EMPLOYEE WHERE SALARY >9999 语句会将错误消息输送到一个名为 9999 的文件。要划清这些特殊符号的界限;您应该输入: SELECT * FROM EMPLOYEE WHERE SALARY ">" 9999

虽然您的用户可能永远不会使用 CLP 来访问他们的数据,对于 DBA 或者应用程序的编程人员来说, CLP 在工具箱中是最基本的工具:它就像是在所有场合都适用的燕尾服。对于关键应用来说,往往数据库是关键之处,如果某个地方出错的话,问题的判定会比较困难。在大型主机/微型计算机领域中,问题可能出在应用程序中,也可能出在软件系统中,但是问题总可以界定在一台计算机以内。而在客户机-服务器领域中,问题可能隐藏在客户机系统软件中(操作系统,数据库客户机,或者通信协议),可能隐藏在客户机应用程序代码中,可能隐藏在服务器应用程序代码中(如果您正在使用触发器,用户定义的函数,或者存储过程),还可能隐藏在服务器上的其他地方。3-层应用包括 Web 服务器、浏览器和第三层的硬件。CLP 在这里有什么用呢?答案就是,它可以将应用程序从这一架构中分割出来。如果您发现一个问题,那么可以将故障请求翻译成简单的 SQL,然后从以下机器上的 CLP 运行该 SQL:

  1. 服务器
  2. 客户机
  3. Web 服务器

根据哪里没问题,哪里有故障,您就可以判定是 DB2 本身有故障(很可能在通过 CLP 提交 SQL的服务器上出故障的形式与客户机应用程序出故障的形式是一样的),还是问题出在通信上(请求在 客户机出了故障,而在服务器上没有问题),或者问题是出在 Web 服务器上(问题只出在最远的地方)。


回页首

帮助

CLP 也是一个到 DB2 帮助的接口。如果您收到一条消息,而又不知道应该采取怎样的适当步骤,那么在 CLP 中输入:

C:\\SQLLIB>db2 ? sql0100 |more

FETCH、UPDATE 或 DELETE 语句的输出中应该有 SQL0100W No 这样一行;否则查询的结果就是一个空表。

解释:下面的情况中有一种情况为真:

  • No 这一行符合在 UPDATE 或 DELETE 语句中指定的搜索条件。
  • SELECT 语句的结果是一个空表。
  • 当游标定位到了结果表的最后一行记录时,会执行一条 FETCH 语句。
  • 在 INSERT 语句中使用的 SELECT 的结果为空。

这里没有检索、更新或者删除数据。

用户响应:不需要动作。处理可以继续。

sqlcode: +100

sqlstate: 02000

您可以看看在 Messages 手册中的相同的帮助,包括为避开问题而建议采用并且可以采用的动作。CLP 还将提供用于 DB2 命令的语法(作为例子,可以试试 DB2 ? backup)。


回页首

脚本编写

您可以使用 CLP 运行脚本,任何可以以常规操作处理的方式运行的实用程序(例如每夜运行的 LOAD、RUNSTATS 或者 BACKUP 命令),都可以是一个 CLP 脚本。CLP 的一些选项可以指定输入文件(-f),一个用于消息的输出文件(-z),是否能够回送关于什么要在屏幕上运行的信息(-v),是否能够设置一个语句终止符(-t),如果设置了这个选项,脚本就可以包含多个 DB2 命令 和 SQL 语句。通常我会这样运行脚本:DB2 -tvf filename.ddl -t,后面加上默认的终止符(;),-v 选项允许回送文件的内容到屏幕(这样就可以检查我告诉了 DB2 要做些什么),-f 选项告诉 CLP 使用一个输入文件。通过 DB2 ? options可以得到关于所有选项的帮助:

C:\\SQLLIB>db2 ? options

db2 [option ...] [db2-command | sql-statement |

[? [phrase | message | sqlstate | class-code]]]

option: -a, -c, -e{c|s}, -finfile, -lhistfile, -n, -o, -p, -rreport, -s, -t,

-td;, -v, -w, -x, -zoutputfile.

选项 描述 默认设置
-a 显示 SQLCA OFF
-c 自动提交 ON
-e 显示 SQLCODE/SQLSTATE OFF
-f 从输入文件读内容 OFF
-l 历史文件中的日志记录命令 OFF
-n 删除换行字符 OFF
-o 显示输出 ON
-p 显示 db2 交互性命令 ON
-r 将输出报告保存到文件 OFF
-s 出现命令错误时停止执行 OFF
-t 设置语句终止符 OFF
-v 回送当前命令 OFF
-w 显示 FETCH/SELECT 警告消息 ON
-x 省略列标题的打印 OFF
-z 将所有输出保存到输出文件 OFF

在 DB2 ControlCenter 中的脚本中心那里提供了更加高级的脚本编写,包括时间安排(scheduling),并且可以使用日志来查看发生过什么事情。在原型(prototyping)模式下,CLP 只是一种启动程序的快速方式。注意上述输出中的 -x 选项:我们添加了这个能力,以便可以在 DB2 v7 的 fixpak 1 中不输出列标题。如果客户要求输出列标题,他们可能是关心列标题,因为他们希望输出好看一些(或者要将输出作为另一个程序的输入)。对于我来说,这意味着人们现在 将 CLP 不仅仅用于原型。


回页首

编写 DDL 脚本

如果对于每个产品和开发数据库您都遵循这个简单的规则,那么您将对我感激不尽:您可以将所有用于创建或更改数据库对象的 DDL 保存在一个文件中。更令人振奋的是,可以用一个编辑器将 DDL 输入到一个文件中,然后通过提交这个文件给 CLP 来运行这个文件。如果您不采纳上述建议,那么用于在一个数据库中重新创建视图、检查约束、SQL 过程以及触发器的语句的文本也可以这样获取:

select text from syscat.views

select text,tabname from syscat.checks

select text from syscat.procedures

select text from syscat.triggers

您也可以通过使用 -e 选项(或者对于特定的表使用 -t 选项和 -e 选项)运行 db2look 来收集将大部分的这些信息。                 DB2 Command Reference 为 db2look 编写了文档。不过,预先将这样的信息保存在一个用于提交 DDL 的文件中,比在一个依赖于另一个数据库的模式的新项目中途匆忙地重新创建它要更显得专业些。


回页首

原型

您不必将所有的 DML(SELECT,INSERT,UPDATE,DELETE)保存在一个文件中。毕竟,这些 DML 将会处在您所编写的程序中,并且可以通过使用像监视器和 DB2 Query Patroller 这样的 DB2 工具动态地捕获。不过,在将 SQL 输入到一个应用程序之前,您可以先使用 CLP 对其进行原型试验,看看自己是否对结果满意(并且可以检查语法)。使用 -a 选项来查看 SQL Communications Area (SQLCA)。例如,如果语句没有对任何东西进行更新,或许在语法上这条语句是对的,但是没有任何记录行符合更新条件是由于采用了限制性非常强的 where 子句造成的。在这种情况下,您会得到一个值为 100 的 SQLCODE:

C:\\sqllib>db2 -a update employee set salary=5 where salary "<" -5

SQLCA Information

sqlcaid : SQLCA   sqlcabc: 136   sqlcode: 100   sqlerrml: 0

sqlerrmc:

sqlerrp : SQLRIEXU

sqlerrd : (1) -31743   (2) 1    (3) 0

(4) 0        (5) 0    (6) 0

sqlwarn : (1)    (2)    (3)    (4)    (5)    (6)

(7)    (8)    (9)    (10)   (11)

sqlstate: 02000


回页首

何时使用 DB2 Command Center

DB2 Command Center 是一个图形化的命令行(对于那些偏爱形而上学逻辑的读者来说,这是一种似是而非的说法,而不是简单的自相矛盾)。任何命令或者 SQL 语句,甚至是操作系统命令,都可以通过 Command Center 提交。虽然 CLP 直接调用 DB2 编程接口,但是 Command Center 要经由 DB2 的 Call Level Interface (即 CLI,这基本上是 ODBC 的一个超集)。这意味着当有故障发生时,您可能会得到一条 CLI 错误消息,而不是一个 SQLCODE。这还意味着如果您怀疑某个地方有 CLI bug,您可以试着通过 CLP 提交 SQL 到 Command Center。如果在 CLP 部分是成功的,而在 Command Center 部分是失败的,那么问题显然就出在 CLI 那一部分。在 DB2 中,这一点很重要,因为对 DB2 的所有 ODBC、Java、JDBC 和 SQLJ 访问都要经由 CLI。由于这个原因,Command Center 是用 Java 编写的。比起 CLP,Command Center 有以下优点:

  1. 可以在操作系统命令提示符的边界外部水平地和垂直地滚动:这包括针对您提交的命令和 SELECT 语句的结果的独立选项卡(或页面)。
  2. 对剪切和粘贴的完全剪贴板支持。
  3. 可以访问 Script Center (在 ControlCenter 中)和 Visual Explain (以便图形化地显示对 SQL 语句的访问计划——这是查看哪些索引得到使用的最佳方式)。可以高亮显示 SQL,通过点击 Access Plan 可以可视化地解释一条 SQL 语句。
  4. 能够更容易地通过用鼠标拓展或者收缩可见区域来显示(或隐藏)多个列。
  5. 提供了一个下拉式的菜单,用于检索和编辑先前提交的命令(而不是依赖于操作系统的命令,比如 Windows 和 OS/2 操作系统中的向上箭头和向下箭头)。
  6. 在会话中提交的命令和结果的更好的历史记录——这有利于将交互式的体验转变成脚本(或者取得所有 CREATE TABLE 语句并将其存入一个文件中)。
  7. 支持所有的 CLP 选项(例如显示 SQLCA)。

因为接口各异,其中有些微妙之处需要知道。接下来的语句在 Command Center 中和在 CLP 中将得到迥然不同的结果:

create user temporary tablespace usetemp

pagesize 4k managed by system using (‘C:\\usetemp‘);

declare global temporary table t1 (col1 int) not logged;

select count(*) from session.t1;

这与 DB2 对用于用户声明的临时表的会话所有权的处理方式有关。对于在 Command Center 中启动的每个 Java 进程,所有权并不是一成不变的。上面的 select count(*) 语句在 CLP 中将获得成功,但是在 Command Center 中却不能找到 session.t1。


回页首

CLP 设计

DB2 Command Reference 在第 2 章中解释了 CLP 设计。CLP 设计由两个过程组成:

  1. 一个前端进程(或者是在 Windows 和 OS/2 上的线程),用于处理与操作系统命令提示符的通信。
  2. 一个后端进程,用于处理与数据库的通信。这确保了在您连接到 DB2 之后,如果用 Control-C 或 Control-Break 中止来自一个大型选择(例如 SELECT * FROM SYSCAT.TABLES)的输出,那么输出会顺利地被中止,而不会断开到 DB2 的连接。

回页首

命令窗口与 Windows 上的 CLP 的比较

那么,为什么 DB2 要求您用 Windows 上的 DB2CMD.EXE(或者用 DB2 Command Window,或者用 DB2 Command Line Processor,又或者用开始菜单)启动一个 CLP 呢?在 UNIX 和 OS/2 上,前端进程和后端进程之间的链接非常简单:如果父进程死亡,则其所有子进程都将被操作系统终止。在 Windows 上,父线程在死亡时并不会终止其子线程。这里我们不去冒险产生 Windows 上的大量 phantom 线程,而是决定用一个 cookie 来为 Windows 上的 CLP 链接前端线程和后端线程。这要求 CLP 要通过 DB2CMD.EXE 来启动。这样做确保了如果杀死了父线程,那么子线程也不会保留下来,从而避免了资源的浪费。不必担心叫做"DB2 Command Processor"的特定选项。它会创建像这样的一个特殊的提示符:

db2 =>

这样,您就不必在所有发送到 DB2 的指令之前都加上 DB2。另一方面,现在您必须在操作系统命令之前加上一个惊叹号(!),就像在 Command Center 中一样。


回页首

何时不使用 命令行处理器

对于用于检查语法和您希望用户看到的结果的原型 SQL 来说,CLP 很有用。但是,由于 CLP 是如此的多用,能够提供到每条 DB2 SQL 语句、命令以及编程接口的访问途径,所以通常来讲,比起动态 SQL(例如那些通过 ODBC 提供的动态 SQL)来 CLP 会产生更大的开销。为了对性能进行原型试验,可以使用 db2batch,这在                  DB2 Command Reference中有文档说明。


回页首

一个需要避免的典型例子(或者说不值得拷贝的例子)

下面是一个简单的例子,其中充斥着许多坏的编程习惯,这个例子展示了为什么 CLP 对于应用程序逻辑来说不是很好。对于简单的脚本编写,下面的例子可以更加强大,甚至可以处理一些出错的情况,如果它是用 PERL 编写的话。不过,对于我来说,编写和做一些有用的工作是十分有趣的。先决条件:

  1. 已经创建了样本数据库。
  2. 从 DIR 命令得到的输出与我测试时所在的系统(带有 ServicePak 5 的 NT 4.0,以及 Windows 2000)相匹配。
  3. 您正处在 Windows 上的一个 DB2 Command Window 中。

回页首

这个例子做些什么

是不是曾经碰到过用完了磁盘空间的情况。下面的例子捕获在 C:\\ 上的一个递归的目录清单的输出,为每个大小为 1 MB 或大于 1 MB 的文件导入一行,并列出 C: 盘中 10 个最大的文件。不要删除 PAGEFILE.SYS!只能删除那些明确知道是垃圾的文件(例如 C:\\TEMP 中大型的 .PDF 文件)。                  这个例子中有什么好的地方?

  1. 它可以帮助我清理我的硬盘。
  2. 它可以在两种系统上工作(我成功地完成了系统测试并发布了它!)

这个例子有什么不好的地方?

在开发者园地即将发布的一个 500 页的自述文件(readme)中,您将看到对这个例子的缺点的文档说明。

仔细研究这个例子: (我是这样运行的:db2 -tvf dirpub)                

!dir c:\\*.* /s>dir.out;

connect to sample;

create table dirlist (size_in_mb int not null, name char(21) not null

CONSTRAINT CHECKBYTES CHECK (name not like ‘ bytes%‘));

import from c:dir.out of asc method l (28 30, 40 60)

commitcount 1000 replace into dirlist;

select * from dirlist order by size_in_mb desc

fetch first 10 rows only;

第 1 行将 C: 上所有文件的列表发送到 dir.out。

第 2 行连接到样本数据库。

第 3 行创建一个带有两列的表:一列是以 MB 为单位的每个文件的大小,一列是每个文件的文件名中的前 21 个字符。既然在 Windows 告诉您关于目录的信息时会显示短语"bytes",那么我们使用一个检查约束来消除这些不需要的行。

第 4 行将文件 dir.out 中的行导入表 dirlist 中。我们假设以 MB 为单位的文件大小是从第 28 列到第 30 列的一个整数,并将从第 40 列到第 60 列的内容拿来作为文件名。我们每 1000 行提交一次,并且替换 dirlist 的内容,以防多次运行这种提交。

第 5 行获得 10 个最大的文件的文件名。

所以,用 5 行代码,我们就可以清理一个硬盘分区(或者至少查看出哪些文件占用了所有的空间)。处理出错情况,允许搜索其他驱动器,以及删除输出中的系统文件,这些功能能够轻松地将这个小小的程序扩展成数百行,我不 想编写这么多的代码。毕竟,CLP 的精神就是“快而脏(quick and dirty)”,即花费的精力中有 20% 满足了 80% 的需求。如果您小心地应用这个 80/20 法则,令用户感到满意,您就总能接到更多的项目。

时间: 2024-10-12 03:26:01

【转】DB2 的命令行处理器和脚本编写的相关文章

DB2——命令窗口和命令行处理器

DB2命令窗口和命令行处理器实际上都是CMD命令窗口生成的,具体区别如下 菜单与可执行文件的对应关系 D:\Program Files\IBM\SQLLIB\BIN\ DB2 命令窗口 - Administrator <----> db2cwadmin.bat DB2 命令窗口 <----> DB2CW.BAT DB2 命令行处理器 <----> DB2CMD.exe 参数为:DB2SETCP.BAT DB2.EXE DB2 命令行处理器加强版 <---->

Beginning Python From Novice to Professional (2) - 命令行运行Python脚本

命令行运行Python脚本 Linux下先创建一个hello.py [python] view plaincopy $ gedit hello.py 输入: [python] view plaincopy #!/usr/bin/env python print 2+2 保存退出,运行: [python] view plaincopy $ python hello.py 4 我们也可以让它变得和普通程序一样执行 执行之前,让脚本文件具备可执行属性: [python] view plaincopy

《Linux命令行与shell脚本编程大全》学习笔记(转)

第一部分:Linux命令行<Linux命令行与shell脚本编程大全> 第一章:初识Linux shell<Linux命令行与shell脚本编程大全> 第二章:走进shell<Linux命令行与shell脚本编程大全> 第三章:基本的bash shell命令<Linux命令行与shell脚本编程大全> 第四章:更多的bash shell命令<Linux命令行与shell脚本编程大全> 第五章:使用Linux环境变量<Linux命令行与she

&lt;&lt;linux命令行与shell脚本编程大全&gt;&gt;学习笔记(1)

一章初识linux shell 一.什么是linux 1.linux系统可大致划分为四部分: l Linux内核 l GNU工具组件 l 图形化桌面环境 l 应用软件 在linux系统里,这四部分中的每一部分都扮演着一个特别的角色,但如果将他们分开,每一部分都没太大的作用. 1)探究linux内核 Linux系统的核心是内核,内核控制着计算机系统上的所有硬件和软件,必要时分配硬件,有时需要执行软件. 内核基本负责以下四项主要功能: l 系统内存管理 l 软件程序管理 l 硬件设备管理 l 文件系

【持续更新中】Linux命令行与Shell脚本编程大全(第3版)读书笔记12-20章

<Linux命令行与Shell脚本编程大全(第3版)>读书笔记 第十二章 使用结构化命令 根据条件使脚本跳过某些命令,这样的命令称为结构化命令(structured command).结构化命令允许改变程序执行的顺序. If-then语句: If command Then Commands Fi 如果if后的command执行退出码是0(也就是执行成功了),then后面的语句就会被执行. 也可以写成: If command; then Commands Fi 注意了,if后的command结果

《Linux命令行与Shell脚本编程大全第2版.布卢姆》pdf

下载地址:网盘下载 内容简介  · · · · · · 本书是一本关于Linux 命令行与shell 脚本编程的全面教程.全书分为四部分:第一部分介绍Linuxshell 命令行:第二部分介绍shell 脚本编程基础:第三部分深入探讨shell 脚本编程的高级内容:第四部分介绍如何在现实环境中使用shell 脚本.本书不仅涵盖了详尽的动手教程和现实世界中的实用信息,还提供了与所学内容相关的参考信息和背景资料. 本书内容全面,语言简练,示例丰富,适合于linux 系统管理员及Linux 爱好者阅读

命令行执行php脚本 中$argv和$argc

在实际工作中有可能会碰到需要在nginx命令行执行php脚本的时候,当然你可以去配置一个conf用外网访问. 在nginx命令行中 使用 php index.php 就可以执行这个index.php脚本了,但是怎么传递参数呢?那就要用到$argv和$aegc了.不用开启什么设置 直接在脚本中使用,类似于http传值中的$_POST和$_GET..在index.php插入以下菜吗 <?php echo $argv[0]; echo "\n"; var_dump($argv[1]);

Linux命令行与shell脚本编程大全.第3版(文字版) 超清文字-非扫描版 [免积分、免登录]

此处免费下载,无需账号,无需登录,无需积分.收集自互联网,侵权通知删除. 点击下载:Linux命令行与shell脚本编程大全.第3版 (大小:约22M) 原文地址:https://www.cnblogs.com/pluse/p/9408724.html

mysql命令行导入sql脚本中文变问号问题

之前一直用工具连接mysql虽然小问题不断也都无伤大雅,最近做金融云项目,只能通过服务器的内网访问数据库,也就是说只能在linux下通过命令行访问,在导入中文的时候发现都变成问号了,经过查询资料解决,特此记录一下思路. 1.检查sql脚本文件是否unicode编码,打开查看是脚本文件中中文是否能正常显示. 2.检查所建好的数据库是否采用utf8编码. 3.在mysql命令行下执行status检查Server characterset和Client characterset编码是否一致(我就是这一