Delphi调用DOS并输出结果集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Delphi调用DOS并输出结果集相关的知识,希望对你有一定的参考价值。

我百度了一下,可是只有代码并不是很清楚,到底是怎么实现的还不知道,希望来者可以写上必要的注释!很感谢

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Memo1:TMemo;

procedure FormClose(Sender:TObject; var Action:TCloseAction);
procedure FormCreate(Sender:TObject);
procedure ress(Sender:TObject; var Key:Char);
private
Private declarations
public
Public declarations
end;

var
Form1 :TForm1;
ReadOut, WriteOut :THandle;
ReadIn, WriteIn :THandle;
ProcessInfo :TProcessInformation;

implementation

$R *.dfm
procedure InitConsole; 设置 console 启动属性
var
Secu :TSecurityAttributes;
start :TStartUpInfo;
buf :array[0..MAX_PATH] of Char;
begin // MAX_PATH
with Secu do
begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
Createpipe(ReadOut, WriteOut, @Secu, 0); 创建一个命名管道用来捕获console程序的输出
Createpipe(ReadIn, WriteIn, @Secu, 0); 创建第二个命名管道用来捕获console程序的输入
GetEnvironmentVariable('comspec', buf, SizeOf(buf));
ZeroMemory(@start, SizeOf(start));
start.cb := SizeOf(start);
start.hStdOutput := WriteOut;
start.hStdInput := ReadIn;
start.hStdError := WriteOut;
start.dwFlags := STARTF_USESTDHANDLES +
STARTF_USESHOWWINDOW;
start.wShowWindow := SW_HIDE;
CreateProcess(nil, buf,
@Secu, @Secu, true,
NORMAL_PRIORITY_CLASS,
nil, nil, start, ProcessInfo);
end;

function ReadFromPipe:string;
var
buf :array[0..1024] of Char;
BytesRead :DWord;
begin

Result := '';

while
BytesRead > 0 do
begin //循环读取数据。

if ReadFile(ReadOut, buf, SizeOf(buf), BytesRead, nil) then

begin
Result := Result + Copy(buf, 1, BytesRead);

WaitForSingleObject(ProcessInfo.hProcess, 10);
// Form1.Memo1.Lines.Add('a ' + inttostr(BytesRead));
end
else
break;

PeekNamedPipe(ReadOut, nil, 0, nil, @BytesRead, nil); //检查管道里是否有数据。
// Form1.Memo1.Lines.Add('b ' + inttostr(BytesRead));
end;
end;

procedure WriteCMD(Value:string);
var
len :integer;
BytesWrite :DWord;
Buffer :PChar;
begin
len := Length(Value) + 2;
Buffer := PChar(Value + #13#10); //命令与内容不出现在一行。
WriteFile(WriteIn, Buffer[0], len, BytesWrite, nil);

end;
procedure CloseConsole;
begin
TerminateProcess(ProcessInfo.hProcess, 0);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadIn);
CloseHandle(WriteIn);
CloseHandle(ReadOut);
CloseHandle(WriteOut);
end;

procedure TForm1.FormClose(Sender:TObject; var Action:TCloseAction);
begin
CloseConsole;
end;

procedure TForm1.FormCreate(Sender:TObject);
begin
InitConsole;

end;

procedure TForm1.ress(Sender:TObject; var Key:Char);
var
s, ss :string;
i, j :integer;
begin
if Key = #13 then
begin
i := Memo1.Lines.Count - 1;
s := Memo1.Lines[i];
delete(s, 1, pos('>', s));
WriteCMD(TRIM(s));
//WaitForSingleObject(ProcessInfo.hProcess, 10000);//WAIT_TIMEOUT);
sleep(1);
// ss := TRIM(ReadFromPipe);
// for j = (Memo1.Lines.Count-1) downto 0 do
// begin
// if Memo1.Lines[j] = '' then Memo1.Lines.delete(j);
// end;
Memo1.Lines.Add(TRIM(ReadFromPipe));
end;
end;
end.

参考资料:http://hi.baidu.com/e%5F%5Fjin/blog/item/6582301759edd8084a90a79c.html

参考技术A Delphi中调用DOS程序并获取DOS程序的输出结果?

很简单。

执行dos程序时,加上输出改向就行了。
如:dos程序abc.exe ,调用执行时这样写: abc.exe > c:\kk.txt
则执行完abc.exe 后,会在C:\中生成一个kk.txt文件,并将其输出结果写到该文件中。然后在Delphi中读取该文件中的内容。
参考技术B windows管道技术
下面有介绍和delphi的例子
http://comeoffbest.blog.163.com/blog/static/9189356520091027114610312/

Oracle 存储过程:返回结果集和输出参数

【中文标题】Oracle 存储过程:返回结果集和输出参数【英文标题】:Oracle stored procedure: return both result set and out parameters 【发布时间】:2018-07-28 01:26:16 【问题描述】:

Oracle存储过程有OUT参数并返回结果集,例如

create or replace procedure foo(empId IN NUMBER, maxSalary OUT NUMBER) AS BEGIN
    select * from Employee e where e.id >=empId;
    select max(salary) into maxSalary from Employee;
END;

错误:

PLS-00428: an INTO clause is expected in this SELECT statement

Mysql存储过程既可以返回结果集,也可以返回out参数。 oracle db怎么做?

【问题讨论】:

【参考方案1】:

在 Oracle 中,您不能在没有 INTO 子句的情况下运行直接选择语句。

如果您使用的是 Oracle 12c 及更高版本,您可以使用 REF CURSORDBMS_SQL.RETURN_RESULT

create or replace procedure foo(empId IN NUMBER, maxSalary OUT NUMBER) AS
q SYS_REFCURSOR;
 BEGIN
    OPEN q FOR select * from Employee e where e.id >=empId;
     DBMS_SQL.return_result (q); -- This will display the result
    select max(salary) into maxSalary from Employee;
END;

对于以前的版本(11g、10g),您可以将REF CURSOR 作为OUT 参数传递并通过作为脚本运行从sqlplus 或TOAD 打印它。

create or replace procedure foo(empId IN NUMBER, maxSalary OUT NUMBER,
   q OUT SYS_REFCURSOR) AS

     BEGIN
        OPEN q FOR select * from Employee e where e.id >=empId;
        select max(salary) into maxSalary from Employee;
    END;

在调用过程之前定义绑定变量。

VARIABLE v_empID NUMBER
VARIABLE v_maxsalary NUMBER
VARIABLE v_q REFCURSOR

EXEC :v_empID := 101
EXEC foo(:v_empID,:v_maxsalary,:v_q ) 
PRINT v_q -- This will display the result from the query.

【讨论】:

能否在SQL Server 2008 中实现相同的功能,告诉我? @WillMarcouiller,是的。 Ms Sql 允许您从存储过程中返回一个或多个数据集。请避免使用游标,这对 Sql 女士来说很慢(例如,只返回表)。在此处查看详细信息:***.com/questions/22963939/…

以上是关于Delphi调用DOS并输出结果集的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程如何输出结果集

如何php调用oracle存储过程返回的是一个结果集,该怎么从php页面中吧数据循环输出呀

Oracle 存储过程:返回结果集和输出参数

MySQL 存储过程,获取使用游标查询的结果集

C#利用反射动态调用DLL并返回结果,和获取程序集的信息

参考光标和结果集