问题描述
美好的一天
汤姆
-
我写信给你,因为我在开发中遇到问题,我需要访问linux服务器来动态提取文件,并使用java库中支持的scp命令将它们放置在我的windows服务器上。但它失败了,因为它告诉我该命令 “既不外部也不内部” 未被识别。
这可能会发生吗?
我附加了我的代码。
非常感谢您的帮助
打电话给终端。
进程错误: 系统找不到指定的路径。
Procedimiento PL/SQL终端更正。
汤姆
-
我写信给你,因为我在开发中遇到问题,我需要访问linux服务器来动态提取文件,并使用java库中支持的scp命令将它们放置在我的windows服务器上。但它失败了,因为它告诉我该命令 “既不外部也不内部” 未被识别。
这可能会发生吗?
我附加了我的代码。
非常感谢您的帮助
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Host" AS import java.io.*; public class Host { public static void executeCommand(String command) { try { String[] finalCommand; if (isWindows()) { finalCommand = new String[4]; // Use the appropriate path for your windows version. //finalCommand[0] = "C:\\winnt\\system32\\cmd.exe"; // Windows NT/2000 finalCommand[0] = "C:\\windows\\system32\\cmd.exe"; // Windows XP/2003 //finalCommand[0] = "C:\\windows\\syswow64\\cmd.exe"; // Windows 64-bit finalCommand[1] = "/y"; finalCommand[2] = "/c"; finalCommand[3] = command; } else { finalCommand = new String[3]; finalCommand[0] = "/bin/sh"; finalCommand[1] = "-c"; finalCommand[2] = command; } final Process pr = Runtime.getRuntime().exec(finalCommand); pr.waitFor(); new Thread(new Runnable(){ public void run() { BufferedReader br_in = null; try { br_in = new BufferedReader(new InputStreamReader(pr.getInputStream())); String buff = null; while ((buff = br_in.readLine()) != null) { System.out.println("Process out :" + buff); try {Thread.sleep(100); } catch(Exception e) {} } br_in.close(); } catch (IOException ioe) { System.out.println("Exception caught printing process output."); ioe.printStackTrace(); } finally { try { br_in.close(); } catch (Exception ex) {} } } }).start(); new Thread(new Runnable(){ public void run() { BufferedReader br_err = null; try { br_err = new BufferedReader(new InputStreamReader(pr.getErrorStream())); String buff = null; while ((buff = br_err.readLine()) != null) { System.out.println("Process err :" + buff); try {Thread.sleep(100); } catch(Exception e) {} } br_err.close(); } catch (IOException ioe) { System.out.println("Exception caught printing process error."); ioe.printStackTrace(); } finally { try { br_err.close(); } catch (Exception ex) {} } } }).start(); } catch (Exception ex) { System.out.println(ex.getLocalizedMessage()); } } public static boolean isWindows() { if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) return true; else return false; } }; / create or replace procedure runOn ( p_cmd in varchar2) as -- Created : 03/09/2018 10:40:00 -- Purpose : Ejecutar comando cmd out scope pl/sql language java name 'Host.executeCommand (java.lang.String)'; / -- DECLARE l_schema VARCHAR2(30) := 'VENTAS'; -- Adjust as required. BEGIN DBMS_JAVA.grant_permission(l_schema, 'java.io.FilePermission', '<>', 'read ,write, execute, delete'); DBMS_JAVA.grant_permission(l_schema, 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', ''); DBMS_JAVA.grant_permission(l_schema, 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', ''); END; / SET SERVEROUTPUT ON SIZE 1000000 CALL DBMS_JAVA.SET_OUTPUT(1000000); begin runOn ('cd c:\com\interfases\entrada'); runOn ('C:\Users\ecorona\Documents\MobaXterm\slash\bin\scp.exe root@999.99.99.999:/root/2018/img/154819-2.jpeg .'); end; / 复制
打电话给终端。
进程错误: 系统找不到指定的路径。
Procedimiento PL/SQL终端更正。
专家解答
好的,我将建议一种不同的方法,因为我认为您会发现它更简单。
首先,我们将创建一个具有预处理器的外部表
现在,文件 'dummy.txt '* 必须 * 存在,但我们不在乎内容-因此,我们只是创建一个空文件
我们真正感兴趣的是 'run_command.cmd' 的内容。因此,我将首先添加作为测试:
然后查询我的表
好的... 您可以看到这是怎么回事-* 查询 * 我的表将 * 运行 * run_command.cmd脚本。
所以现在我将用UTL_FILE来增强它
所以动态改变脚本的内容也有效。因此,我们可以将其包装在一个函数中,以使其易于使用
就这样。运行带有select语句的主机命令。
现在 * 显然 * 你不会有一个只需要 * 任何 * 参数并盲目运行的函数-这是一个巨大的风险。但是在您的情况下,该函数可能仅采用文件名,然后在utl_file.put_line调用中编写适当的scp命令。
但是您可以看到这是如何工作的-并且比java存储的proc更容易调试/维护。
首先,我们将创建一个具有预处理器的外部表
SQL> create or replace directory TEMP as 'c:\temp'; Directory created. SQL> create or replace directory BIN as 'c:\bin'; Directory created. SQL> SQL> create table host_command_external 2 ( text varchar2(4000) ) 3 organization external 4 ( 5 type oracle_loader 6 default directory temp 7 access parameters 8 ( 9 records delimited by newline nologfile 10 preprocessor bin: 'run_command.cmd' 11 fields terminated by whitespace 12 ( text position(1:4000) ) 13 ) 14 location ('dummy.txt') 15 ) 16 reject limit unlimited; Table created.复制
现在,文件 'dummy.txt '* 必须 * 存在,但我们不在乎内容-因此,我们只是创建一个空文件
SQL> host touch c:\temp\dummy.txt复制
我们真正感兴趣的是 'run_command.cmd' 的内容。因此,我将首先添加作为测试:
c:\bin\run_command.cmd =============== @echo off echo This is a test复制
然后查询我的表
SQL> select * from host_command_external; TEXT ------------------------------------------ This is a test复制
好的... 您可以看到这是怎么回事-* 查询 * 我的表将 * 运行 * run_command.cmd脚本。
所以现在我将用UTL_FILE来增强它
SQL> declare 2 f utl_file.file_type; 3 begin 4 f := utl_file.fopen('BIN','run_command.cmd','w'); 5 utl_file.put_line(f,'C:\bin\usr\local\wbin\ls -l c:\temp'); 6 utl_file.fclose(f); 7 end; 8 / PL/SQL procedure successfully completed. SQL> select * from host_command_external; TEXT ------------------------------------------------------------------------------------------------------ c:\oracle\product\12.2\DATABASE>C:\bin\usr\local\wbin\ls -l c:\temp total 1971276 -rw-rw-rw- 1 user group 105791 Jun 2 2017 122_download_now.jpg -rw-rw-rw- 1 user group 134220 Sep 12 2017 12c.png -rw-rw-rw- 1 user group 248032 Aug 23 11:08 18c_pic1.jpg -rw-rw-rw- 1 user group 414154 Aug 23 11:08 18c_pic2.jpg复制
所以动态改变脚本的内容也有效。因此,我们可以将其包装在一个函数中,以使其易于使用
SQL> create or replace 2 function host_command(p_command varchar2) return sys.odcivarchar2list pipelined is 3 f utl_file.file_type; 4 begin 5 f := utl_file.fopen('BIN','run_command.cmd','w'); 6 utl_file.put_line(f,p_command); 7 utl_file.fclose(f); 8 9 for i in ( select * from host_command_external ) 10 loop 11 pipe row ( i.text ); 12 end loop; 13 return; 14 end; 15 / Function created. SQL> SQL> select * from host_command('C:\bin\usr\local\wbin\ls -l c:\temp'); COLUMN_VALUE ------------------------------------------------------------------------------------------- c:\oracle\product\12.2\DATABASE>C:\bin\usr\local\wbin\ls -l c:\temp total 1971276 -rw-rw-rw- 1 user group 105791 Jun 2 2017 122_download_now.jpg -rw-rw-rw- 1 user group 134220 Sep 12 2017 12c.png -rw-rw-rw- 1 user group 248032 Aug 23 11:08 18c_pic1.jpg -rw-rw-rw- 1 user group 414154 Aug 23 11:08 18c_pic2.jpg复制
就这样。运行带有select语句的主机命令。
现在 * 显然 * 你不会有一个只需要 * 任何 * 参数并盲目运行的函数-这是一个巨大的风险。但是在您的情况下,该函数可能仅采用文件名,然后在utl_file.put_line调用中编写适当的scp命令。
但是您可以看到这是如何工作的-并且比java存储的proc更容易调试/维护。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle DataGuard高可用性解决方案详解
孙莹
504次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
482次阅读
2025-04-15 17:24:06
墨天轮个人数说知识点合集
JiekeXu
405次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
398次阅读
2025-04-08 09:12:48
Oracle SQL 执行计划分析与优化指南
Digital Observer
373次阅读
2025-04-01 11:08:44
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
360次阅读
2025-04-18 14:18:38
Oracle 19c RAC更换IP实战,运维必看!
szrsu
343次阅读
2025-04-08 23:57:08
oracle定时任务常用攻略
virvle
316次阅读
2025-03-25 16:05:19
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
315次阅读
2025-04-15 14:48:05
风口浪尖!诚通证券扩容采购Oracle 793万...
Roger的数据库专栏
311次阅读
2025-03-24 09:42:53