简介
本文适用于那些至少偶而会编写 sql 和使用 emacs 的应用程序开发人员或数据库程序员。它描述一些为在舒适和安全的 emacs 环境下增强与 ibm db2® 的交互而设计的实用技巧。当然,这里大量谈及的 emacs 也广泛适用于其它商业和开放源码数据库系统。
图 1 是样本会话的抓屏,在这个样本会话中,我以 sql 方式设置了一个临时缓冲区,并在另一个窗口中指定了特定的数据库连接;现在,我可以输入我想执行的任何 sql 命令并通过使用下面描述的 sql-send-region 的键盘快捷方式来强制执行它们。
图 1. 带 db2 clp 的样本 emacs 会话
简单介绍 emacs
长久以来,大多数 dbms 都有一个命令行界面,带 clp 的 db2 也不例外。象“控制中心(control center)”之类的交互式 gui 很适合于浏览和管理数据库之类的任务;然而,我确实发现很多情况下,通过编写 sql 代码和通过 clp 执行该代码来管理或操作数据要方便得多。当执行这类事情时,emacs 特别有用。
我最欣赏 emacs 的地方是,一旦您经过努力,使某件事情在其中工作时,作为运行应用程序结果产生的任何输出都是完全可选的,并且可以粘贴到另一个 emacs 缓冲区或窗口环境中的任何其它地方。您有多少次盯着某一特定应用程序窗口中的文本却无法选择它,而不得不采取记住它或将它写在纸上再将它输入到另一个应用程序中呢?
在关注设置和最初的配置问题之后,emacs 往往会成为非常牢固的平台,您可在其上完成您的工作。不必详尽地定制它,但当您阅读联机帮助和其它文档(emacs 一直以它自己是一个完全自记载的编辑器而自豪)时,您自己会发现编写宏可使事情变得更加容易。然后,您会发现只需编写极少几段 lisp 以进行进一步定制,最终,您将不必编写完整的 lisp 函数。
本文侧重于 windows® 32 位环境,因为现今大多数工作环境的事实是:占主导地位的平台通常是 win32 机器。在 unix® 机器上设置 sql 方式往往稍微容易些。
设置 emacs 的 sql 方式
如果使用 gnu emacs 或 xemacs,您将发现 sql 方式是与该分发版一起提供的。缺省情况下,emacs 被配置成如果装入扩展名为 .sql> 的文件(如 myfuncs.sql),将自动将其缓冲区设置为 sql 方式。输入 c-h m 将为您提供(与处于所有 emacs 方式一样)一个非常特定的列表,它列出了所有适用的命令和击键绑定。这是一个非常便捷的特性;我发现为您经常使用的方式花一些时间学习特定于方式的命令将为您以后省去许多花在输入上的时间。
如果装入扩展名不是 .sql 的文件,则可以通过在 minibuffer 中输入 m-x sql-mode 来手工将它设置成 sql 方式。为了强制总是以 sql 方式装入那些带非标准扩展名(例如:a.sq、b.sq)的文件,可将下列命令添加到 emacs 初始化文件中(通常,.emacs 在 home> 目录中):
(setq auto-mode-alist (append (list ;; insert entries for other modes here if needed. (cons "\\.sq$" ''sql-mode)) auto-mode-alist))
输入 c-h v auto-mode-alist 非常有益;它向您显示已定义的方式与文件扩展名的关联的最新列表。快速浏览它可以看到我所不知道的更多语言。以下是运行该命令的摘录,它显示了其中几项。注:这表示将装入任何扩展名为 .sql 的文件,其缓冲区设置成 sql-mode;同样,以 tar-mode 装入扩展名为 .tar 的文件。
... ("\\.sql\\''" . sql-mode) ("\\.tar\\''" . tar-mode) ("\\.tcl\\''" . tcl-mode) ...设置语法突出显示
彩色和突出显示真正有助于显示复杂信息。您将需要单独启用 font-lock 方式来查看彩色的 sql 代码。emacs 的不同版本执行这一操作的方法有所不同;在 emacs-19 和更早版本中,必须使用 hilit-19 包。本文将不讨论这个问题。emacs-20 和更高版本使用我们将在这里讨论的 font-lock 包。
这里是在 font-lock 方式下开始着色的一些 lisp 代码。
(add-hook ''sql-mode-hook ''font-lock-mode)
不过,您可能希望稍微定制一下 sql 方式,下面给出了一段允许您这样做的代码。这符合为 emacs 中的所有方式启用彩色和 font-lock 的常规机制。
(require ''font-lock)(defun my-turn-on-font-lock () ;; a few enhancements to the presentation. ;; show bold fonts with a blue background (set-face-background ''bold "lightblue") ;; quoted string presentation (set-face-foreground ''font-lock-string-face "mediumslateblue") ;; function name color (set-face-foreground ''font-lock-function-name-face "seagreen") ;; function names in bold (set-face-bold-p ''font-lock-function-name-face t) ;; i like having the currently selected region show up in grey. ;; region color in transient mark mode (set-face-background ''region ''"lightgrey") (transient-mark-mode 1) ;; this is critical (font-lock-mode 1))(defun my-window-setup-hook () ;; the cursor will really stand out! (set-cursor-color "red") (my-turn-on-font-lock));;; you may repeat the add-hook for other modes as well(add-hook ''sql-mode-hook ''my-window-setup-hook)
作为注脚,我必须提一下,您可以运行 m-x font-lock-fontify-buffer 来强制缓冲区成为“字体化的”。然而,在进行了如上所示的设置之后,您不需要这样做。
图 2 是两个缓冲区的抓屏:下面那个缓冲区是 sql 方式,并启用了彩色语法突出显示;另一个缓冲区显示了完全相同的信息,但不是彩色的。添加颜色可以增强可读性。当然,这里显示的示例并不是 db2 平台真正有效的 sql,但这没有关系。
图 2. 正在起作用的 font-lock 方式
从 emacs 中启动 sql 会话
emacs 中 sql 方式的工作方式如下:通过命令行(在 db2 中是 clp)启动与数据库通信的进程。该进程在正在运行的 emacs 实例中有其自己的缓冲区。您发出的任何 sql 命令实际上都作为输入发送到该缓冲区(通过通用的 comint[command-interpreter-in-a-buffer package] 方式或它的某种派生方式)。该方式担当库数据包,并向您提供历史记录和作业控制,比如,就象您可以在 shell 方式缓冲区中做的那样。
在大多数 unix 平台上,sql 方式工作很方便;您只要发出适当的 sql 命令来启动上述的 sql 进程缓冲区。对于 db2,只要发出 m-x sql-db2。
至于 windows 平台上的 emacs,在运行 m-x sql-db2 时有一个问题。会返回下列消息:
db21061e command line environment not initialized.process sql exited abnormally with code 8
我在 comp.databases.ibm-db2 新闻组上公布了对此问题的一种手工修正方法,而我收到的 ian d. bjorhovde 的回应,则是一种更好的方法,完全可以合并到 emacs 的初始化设置中。将下列内容添加到 .emacs 文件:
;;; change the path to db2cmd to reflect the correct;;; location for your machine.(setq sql-db2-program "c:/sqllib/bin/db2cmd.exe");;; the interesting options here is the "-t" option;;; passed to "db2". this is extremely handy - it;;; means that '';'' (semicolon) ; is treated as the command;;; line terminator. the default is to treat the end-of-line;;; as a sql statement terminator.;;; you may look up the command reference online for an;;; explanation of the rest.(setq sql-db2-options ''("-c" "-i" "-w" "db2" "-tv"))单击这里查看该讨论的完整思路。
设置环境之后,应该能够在 win32 平台上与 db2 clp 进行无缝地交互。
查看长数据行
您可能注意到显示长文本行时 emacs 中的缺省设置是自动换行,使所有文本都能同时看到。当查看来自 sql 查询的很宽的结果数据行时,您很可能希望避免换行,以便数据以整齐的表格式的方式显示,而且可以看到列之间垂直对齐。这就需要 toggle-truncate-lines 命令来解救了。
使用 m-x toggle-truncate-lines 来启用行截断,再次使用该命令以关闭它。可以使用 c-x < 和 c-x >(向右和向左拉动滚动条)命令来左右拉动滚动条。emacs-21 处理 c-x e 和 c-x a 比 emacs-20 好。emacs-21 使滚动条处在实际的行结束和开始位置,而 emacs-20 似乎只是使其处在您所查看的范围内。
这个命令不仅在查看 sql 输出时很有用,而且对于查看任何带长文本行的缓冲区也很有用。我经常使用它,使得我发现如下定义别名很有用:
(defalias ''tt ''toggle-truncate-lines)
图 3 显示了两个缓冲区,每个缓冲区都有来自 sql 查询的相同信息,只是一个启用了行截断,一个则没有了。
图 3. 行截断使查看 sql 查询结果变得更加方便
维护多个 sql 会话
如今在大多数环境中,您都需要同时与多个数据库进行交互,这是很常见的事情。例如,您可以有一个开发数据库、一个测试数据库和一个生产数据库。
由于 sql 方式缓冲区与单个数据库关联而且在该缓冲区中执行的所有命令都指向该数据库,所以您可能想知道如何指向不同的数据库。答案在于理解任何被强制为 sql 方式的缓冲区在缺省情况下都会将其自身与在变量 sql-buffer 中命名的 sql 缓冲区关联。通常,这个缓冲区称为“*sql*”。
要启用多个连接和多个缓冲区,可使用下面的代码序列:
m-x sql-db2 ;; connect to a database (say "db2x"); ;; this forces a buffer called "*sql*" to be created. ;; visit "*sql*" and rename it m-x rename-buffer ;; rename to "*sql db2x" ;; now visit a buffer, say "test1.sql" m-x sql-mode ;; test1.sql is now associated with buffer "*sql db2x" m-x sql-db2 ;; connect to a database (say "db2y") ;; visit newly created buffer "*sql*" and rename it m-x rename-buffer ;; rename to "*sql db2y" ;; now visit a buffer, say "test2.sql" m-x sql-mode ;; test2.sql is now associated with buffer "*sql db2y"
也可以通过访问该缓冲区并使用 m-x sql-set-sqli-buffer 为 sql 方式的任何缓冲区手工设置或改变关联的缓冲区。
快速方便地执行 sql 代码
正如我先前提到的那样,以 sql 方式工作的关键是在使用 sql-db2 命令建立数据库连接之后使缓冲区处于 sql 方式。对于 emacs 的爱好者,除了 emacs 之外,没有任何一个 ide 可以象 emacs 这样方便地用来访问文件、进行编辑并保存文本……,添加 sql 执行能力也是很容易的。使缓冲区处于 sql 方式之后,我发现下列命令是最有用的:
c-c c-c: - sql-send-paragraph。该命令允许只将当前段落发送到 db2 clp 解释器;然而,您需要考虑您对段落的想法可能不同于对 sql 方式的想法。
c-c c-r: - sql-send-region。用鼠标或击键选择区域之后,该命令允许将当前所选的区域发送到 db2 clp 解释器。这对于建立原型,做快速的测试,或者在您想要执行已存储很久的现有文本块时。
c-c c-b: - sql-send-buffer。这是当您想要执行整个缓冲区内容时要做的事情。
单击时使 .sql 文件在 emacs 中显示
单击文件使它在已运行的 emacs 窗口中显示很方便。通过使用用于 windows 的 gnuserv 程序就可以做到。图 4 是一个抓屏,它显示了图标以及 windows 被告知这些文件与 emacs“关联”后图标外观的变化。双击所示的目录中的所有文件(除 x.del 外),会在一个已运行的 emacs 实例中打开它们。
图 4. 将 .sql 与 emacs 关联
下面是可在 .emacs 文件中使用的样本设置。
;; setting the exec-path variable is so you can avoid cluttering your;; path env variable since really, only emacs needs to know of it.(setq exec-path (append exec-path ''("c:\\roy\\emacs-21.1\\gnuserv\\release")));; explicitly load the feature; else you can put the gnuserv file in your load-path;; and do a (require ''gnuserv) instead.(load-file "c:/emacs-21.1/gnuserv/gnuserv.el");; (require ''gnuserv);; note: you can kill an already running gnuserv subprocesses by running gnuserv-start;; with an argument, as in c-u m-x gnuserv-start(gnuserv-start);; use this command so that the main emacs frame is the one the opened file will appear in.(setq gnuserv-frame(selected-frame))然后,必须告诉 windows,您想要用 emacs 打开所有 .sql 文件;按照下列步骤做到这一点:
- 打开 windows 资源管理器。
- 在 .sql 文件的文件图标上单击鼠标右键。
- 选择 open with > choose program > gnuclientw。
请阅读 gnuserv 文档,以获取有关 gnuclientw 和 gnuclient 之间差异的详细信息。
或者,可以在 .bat 文件中使用 assoc 和 ftype 程序。我相信设置存储在注册表中,所以您只需做一次就够了!
@rem you may repeat this for other filename extensions as well...assoc .sql=sql_fileftype sql_file=c:/emacs-21.1/gnuserv/gnuclient.exe "%1"
将表中的数据导出至文件
在使用关系数据期间,您迟早都会需要将数据从文件导入到表中,或将表中的数据保存到文件系统上的文件中。这好象与 emacs 在数据库开发环境中的使用没有直接有关;这样做的依据是:如果数据在文件中,将数据读入 emacs,使用 emacs 表达式进行修改,然后将它装回表中有时候会更容易。
要将表导出到文件:
export to "c:/temp/table1.txt" of del modified by coldel0x09 select distinct * from table1;
del 关键字代表“定界 ascii”,其中,定界符是在 modified by 子句中指定的制表符。当然,可以使用任何其它值来代替十六进制 0x09;只要绝对确保您选择的定界符不同于正在导出的数据中的所有字符。
要将文件导入表中:
-- use delete if you are sure you want to clean out the table.-- delete from table1;import from "c:/table1.txt" of del modified by coldel0x09 insert into table1;
结束语
精通联机帮助和阅读 sql 方式的某些源 lisp 代码是增强您熟练运用该环境的重要方法。当您需要快速查询或修改数据库时,您一定会意识到您可以用与外科手术差不多的精确度来访问数据库、正确地执行所需的操作、然后离开。
一旦您掌握了这里所提供技巧的实用知识,您就可能想知道是否有更多技巧,而且往往的确存在这些技巧。查找有关 emacs 技巧的最好地方也许就是 gnu emacs 网站:http://www.gnu.org/software/emacs/emacs.html。http://www.emacswiki.org 的 emacs wiki 也具有极好的参考资源。如果您还不知道 wiki,那么告诉您,它更象一个真实的公告牌,允许访问者在访问和阅读网页时对它们进行添加或修改。