如何定义在启动sql-mode时运行的命令?

时间:2014-11-05 15:57:35

标签: oracle emacs sql-mode comint-mode

我使用Sql-mode连接到Oracle数据库。 linesize和pagesize以及colsep的默认设置并不理想,所以我希望Emacs在连接到我的数据库时自动运行以下命令:

SET COLSEP "|"
SET LINESIZE 9999
SET PAGESIZE 9999

我该如何做到这一点?

3 个答案:

答案 0 :(得分:3)

要始终运行命令,它们可以包含在login.sql文件中。 http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch2.htm#i1133106。但是,这将运行命令,无论SQL * Plus是从Emacs内部运行还是不运行。

答案 1 :(得分:3)

改编自Tobias的早期回答,正确指出使用sql-login-hook通过comint函数发送SQL。

使用Postgres我需要单独发送每个命令,所以我在这里使用comint-send-string来做(并且sql.el维护者迈克尔已经表明这确实是首选方法)。

另请注意,由于所有数据库产品都使用相同的sql-login-hook,因此在发送特定于产品的命令之前检查sql-product是个不错的主意。在这种情况下,我已经包含了对Oracle的检查。

(add-hook 'sql-login-hook 'my-sql-login-hook)

(defun my-sql-login-hook ()
  "Custom SQL log-in behaviours. See `sql-login-hook'."
  (when (eq sql-product 'oracle)
    (let ((proc (get-buffer-process (current-buffer))))
      (comint-send-string proc "SET COLSEP \"|\";\n")
      (comint-send-string proc "SET LINESIZE 9999;\n")
      (comint-send-string proc "SET PAGESIZE 9999;\n"))))

请注意,您应该在命令末尾包含换行符,以便在以交互方式提交命令时复制键入 RET 。 (如果你不这样做,命令仍然会被输入',但是在你提示时手动输入 RET 之后才会生效。

如果仍然无法正常工作,请注意sql-login-hook只有sql-product-interactive才会识别缓冲区中的交互式SQL提示符。使用正则表达式sql-prompt-regexp(使用sql-product-alist中的每个产品默认值建立)来匹配此提示。如果默认模式与您的提示不符,您可以在sql-interactive-mode-hook中修改它。

例如,以下内容允许Postgres提示在数据库名称中包含符号组成字符(例如下划线_)以及单词构成字符:

(add-hook 'sql-interactive-mode-hook 'my-sql-interactive-mode-hook)

(defun my-sql-interactive-mode-hook ()
  "Custom interactive SQL mode behaviours. See `sql-interactive-mode-hook'."
  (when (eq sql-product 'postgres)
    ;; Allow symbol chars in database names in the prompt.
    ;; Default postgres pattern was: "^\\w*=[#>] " (see `sql-product-alist').
    (setq sql-prompt-regexp "^\\(?:\\sw\\|\\s_\\)*=[#>] ")))

答案 2 :(得分:1)

您的LOGIN.SQL会影响许多Oracle会话,包括Emacs以外的会话。

专门为在Emacs中配置SQL命令工具添加了"sql-login-hook"。正如“phils”指出的那样,使用comint-send-string'是发送命令的首选方式。如果您正在寻找响应并需要解析响应,请使用"sql-redirect-value"

我设置LINESIZE 32767 PAGESIZE 50000(他们的最大值)并使用C-prior和C-next向右和向左滚动。