Chinaunix首页 | 论坛 | 博客

-

  • 博客访问: 4152099
  • 博文数量: 172
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1923
  • 用 户 组: 普通用户
  • 注册时间: 2018-12-20 14:57
文章分类
文章存档

2021年(19)

2020年(81)

2019年(68)

2018年(4)

我的朋友

分类: 敏捷开发

2020-02-17 15:52:50


集算器提供了 ODBC 接口,C# 可以通过集算器 ODBC 调用 SPL。

ODBC 服务

安装集算器 ODBC 驱动

使用集算器 ODBC,首先客户端需要安装 ODBC 驱动,在集算器安装路径下的 bin 目录中,用管理员权限执行 esprocOdbcinst.exe,即可安装集算器 ODBC 的驱动程序。

启动 ODBC 服务

在集算器的 [安装根目录]\esProc\bin 中,双击 esprocs.exe 文件(在 Linux 系统中,可以运行 ServerConsole.sh 来启动服务窗口),弹出如下服务窗口:

imagepng

选择 Odbc Server ,点击【Config】按钮,可以打开集算器 ODBC 服务窗口如下:

imagepng

ODBC 服务配置中主要配置 IP、ODBC 服务的端口、允许访问的用户名和密码。配置完成后,点击【OK】,保存配置。然后点击【start】启动服务。

添加 ODBC 数据源

驱动程序安装成功后,可以添加对应的 ODBC 数据源,选择 EsprocOdbc ODBC Driver

imagepng

在弹出的配置窗口中,配置集算器 ODBC 的连接参数,数据源名称用户可自定义,IP、端口、用户名密码等参数要与服务器中的配置一致,如:

imagepng

点击 Connect Test 可以测试连接,如果配置正确,会显示测试连接成功:

imagepng

C# 调用

执行 SPL 语句

比如创建一个数据表,并添加两个字段 baseNum、square2,分别将 100 以内的自然数及其的平方值组成 100 条记录插入到数据表中,最后将表中的数据作为结果集返回。

C# 代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

using System.ComponentModel;

using System.Text;

using System.Data.Odbc;

namespace ODBCtest

{   

classDB

    {

publicvoid rset(OdbcConnectionconn, string selectSql)

        {

OdbcCommandcmd = newOdbcCommand(selectSql, conn);

OdbcDataReader reader = cmd.ExecuteReader();

int nCount = 0;

//循环输出列名

for (int i=0; i< reader.FieldCount;i++)

            {

Console.Write( reader.GetName(i) + "\\t");

            }

Console.Write("\\n");

while (reader.Read())

            {

Console.Write(reader.GetInt32(0) + "\t");

Console.WriteLine(reader.GetInt32(1) + "\\t");

                nCount++;

            }

Console.WriteLine("while end column="\+ reader.FieldCount);

Console.WriteLine("while end row=" \+ nCount);

        }

    }

classProgram

    {

staticvoid Main(string\[\] args)

        {

//生成ODBC连接字符串,其中DSN、UID、PWD属性依次表示ODBC数据源名称、用户名、密码

stringconstr = "DSN=EsprocOdbc;"\+ "UID=user0;"\+ "PWD=123;";

OdbcConnectionconn = newOdbcConnection(constr);

            conn.Open();

//要执行的SPL语句

stringspl = "10.new(~:baseNum,~*~:square2)";

DBdb = newDB();    

               db.rset(conn, spl);

Console.Write("end....");

Console.ReadKey();

            conn.Close();

        }

    }   

} 
	
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.ComponentModel; using System.Text; using System.Data.Odbc; namespace ODBCtest {    classDB     { publicvoid rset(OdbcConnectionconn, string selectSql)         { OdbcCommandcmd = newOdbcCommand(selectSql, conn); OdbcDataReader reader = cmd.ExecuteReader(); int nCount = 0; //循环输出列名 for (int i=0; i< reader.FieldCount;i++)             { Console.Write( reader.GetName(i) + "\\t");             } Console.Write("\\n"); while (reader.Read())             { Console.Write(reader.GetInt32(0) + "\t"); Console.WriteLine(reader.GetInt32(1) + "\\t");                 nCount++;             } Console.WriteLine("while end column="\+ reader.FieldCount); Console.WriteLine("while end row=" \+ nCount);         }     } classProgram     { staticvoid Main(string\[\] args)         { //生成ODBC连接字符串,其中DSN、UID、PWD属性依次表示ODBC数据源名称、用户名、密码 stringconstr = "DSN=EsprocOdbc;"\+ "UID=user0;"\+ "PWD=123;"; OdbcConnectionconn = newOdbcConnection(constr);             conn.Open(); //要执行的SPL语句 stringspl = "10.new(~:baseNum,~*~:square2)"; DBdb = newDB();                    db.rset(conn, spl); Console.Write("end...."); Console.ReadKey();             conn.Close();         }     }    }

执行结果:

imagepng

在 SPL 中访问本地文件

通过 SPL 还可以访问本地的文件,其中包括 Txt、Excel、Json、Csv、Ctx 等多种类型的文件,访问时可以通过绝对路径查文件位置,也可以通过相对路径查找,使用相对路径时,则是相对于配置文件中的主目录,所以,首先我们来配置下主目录:
在 raqsoftConfig.xml 文件的节点 < Esproc > 中添加以下节点:

 

D:\\mainFile 
	
  <mainPath>D:\\mainFilemainPath>

我们把要调用的文件 employee.txt 放到主目录下面,在 C# 中调用时,建立连接等部分的代码与上例是完全相同的, SPL 语句部分如下:

stringspl = "=file(\\"employee.txt\\").import@t()";//SPL语句 
	
stringspl = "=file(\\"employee.txt\\").import@t()";//SPL语句

这里支持绝对路径与相对路径的使用。

结果集输出部分代码如下:

while (reader.Read())

            {

Console.Write(reader.GetInt32(0) + "\\t");

Console.Write(reader.GetString(1) + "\\t");

Console.Write(reader.GetString(2) + "\\t");

Console.Write(reader.GetString(3) + "\\t");

Console.Write(reader.GetString(4) + "\\t");

Console.Write(reader.GetDate(5).ToString("yyyy-MM-dd") \+ "\\t");

Console.Write(reader.GetDate(6).ToString("yyyy-MM-dd") \+ "\\t");

Console.Write(reader.GetString(7) + "\\t");

Console.WriteLine(reader.GetInt32(8) );

                nCount++;

            } 
	
while (reader.Read())             { Console.Write(reader.GetInt32(0) + "\\t"); Console.Write(reader.GetString(1) + "\\t"); Console.Write(reader.GetString(2) + "\\t"); Console.Write(reader.GetString(3) + "\\t"); Console.Write(reader.GetString(4) + "\\t"); Console.Write(reader.GetDate(5).ToString("yyyy-MM-dd") \+ "\\t"); Console.Write(reader.GetDate(6).ToString("yyyy-MM-dd") \+ "\\t"); Console.Write(reader.GetString(7) + "\\t"); Console.WriteLine(reader.GetInt32(8) );                 nCount++;             }

执行结果:

imagepng

对于这种简单运算,还可以使用简单 SQL 语法:

stringspl = "$select * from employee.txt"; 
	
stringspl = "$select * from employee.txt";

其中 $ 表示访问本地文件系统,两种写法的结果集相同。

带参数的 SPL 语句

参数是 SQL 语句的一个重要组成部分,同样,SPL 语句中也支持参数的使用,例如,像上例中,要查询 employee.txt 文件中的数据,但是要求只查询工资在 10000 到 15000 之间的记录,并根据工资升序排序:

调用部分代码如下:

stringspl = "$select * 
              from employee.txt 
              where SALARY > ? and SALARY< ? 
              order by SALARY"; 
	
stringspl = "$select * from employee.txt where SALARY > ? and SALARY< ? order by SALARY";

其中用?表示参数。

rset 方法中的传参部分代码如下:

OdbcCommandcmd = newOdbcCommand(selectSql, conn);

          cmd.Parameters.Add("arg1", OdbcType.Int).Value = 10000;

          cmd.Parameters.Add("arg2", OdbcType.Int).Value = 15000; 
	
OdbcCommandcmd = newOdbcCommand(selectSql, conn);           cmd.Parameters.Add("arg1", OdbcType.Int).Value = 10000;           cmd.Parameters.Add("arg2", OdbcType.Int).Value = 15000;

执行结果:

imagepng

有数据源的 SPL 语句

集算器既然是个数据计算工具,那么数据来源的重要途径之一就是数据库了,C# 中如何来调用带数据源的 SPL 语句呢?往下看:
    C# 调用带数据源的 SPL 语句之前,需要先在应用项目中添加对应的数据库驱动,然后在配置文件 raqsoftConfig.xml 中配置数据源信息。
例如:调用的 SPL 语句中使用的数据源名称为 dm,数据库类型为 HSQL,那么配置如下:
首先,将 HSQL 的数据集驱动 hsqldb.jar 加载到应用项目中;
其次,在 raqsoftConfig.Xml 的 < Runtime > 节点中配置数据源信息:









 



 







 



 























 
	
<DBList> <DB name="dm"> <property name="url" value="jdbc:hsqldb:hsql://127.0.0.1/demo" />  <!\-\- url连接--> <property name="driver" value="org.hsqldb.jdbcDriver" />   <property name="type" value="13" /> <property name="user" value="sa" />   <property name="password" value=""/>   <property name="batchSize" value="1000" /> <property name="autoConnect" value="true" /> <property name="useSchema" value="false" /> <property name="addTilde" value="false" /> <property name="dbCharset" value="UTF-8" /> <property name="clientCharset" value="UTF-8" /> <property name="needTransContent" value="false" /> <property name="needTransSentence" value="false" /> <property name="caseSentence" value="false" /> DB> DBList>

现在我们通过 SPL 从 dm 数据源中查询 SALES 表,过滤出 SELLERID 为 3 的员工,在 2014 年 11 月 11 号到 2014 年 12 月 12 号期间的所有订单信息:

调用部分代码如下:

stringspl = "$(dm)select * 
             from SALES  
             where  SELLERID = ? and  ORDERDATE>TO\_DATE(?,'YYYY-MM-DD') and  ORDERDATE
		
	
stringspl = "$(dm)select * from SALES   where  SELLERID = ? and  ORDERDATE>TO\_DATE(?,'YYYY-MM-DD') and  ORDERDATE;

rset 方法中参数传递部分代码如下:

 cmd.Parameters.Add("arg1", OdbcType.Int).Value = 3;

   cmd.Parameters.Add("arg2", OdbcType.Date).Value = "2014-11-11";

 cmd.Parameters.Add("arg3", OdbcType.Date).Value = "2014-12-12"; 
	
 cmd.Parameters.Add("arg1", OdbcType.Int).Value = 3;    cmd.Parameters.Add("arg2", OdbcType.Date).Value = "2014-11-11";  cmd.Parameters.Add("arg3", OdbcType.Date).Value = "2014-12-12";

结果集输出部分代码如下:

while (reader.Read())

            {

Console.Write(reader.GetInt32(0) + "\\t");

Console.Write(reader.GetString(1) + "\\t");

Console.Write(reader.GetInt32(2) + "\\t");

Console.Write(reader.GetDecimal(3) + "\\t");

Console.WriteLine(reader.GetDateTime(4).ToString("yyyy-MM-dd HH????????ss") \+ "\\t");

                nCount++;

            } 
	
while (reader.Read())             { Console.Write(reader.GetInt32(0) + "\\t"); Console.Write(reader.GetString(1) + "\\t"); Console.Write(reader.GetInt32(2) + "\\t"); Console.Write(reader.GetDecimal(3) + "\\t"); Console.WriteLine(reader.GetDateTime(4).ToString("yyyy-MM-dd HH????????ss") \+ "\\t");                 nCount++;             }

执行结果:

imagepng

执行 SPL 脚本

C# 调用 ODBC,除了可以直接执行单句的 SPL 语句,还可以调用更复杂的 SPL 脚本(后缀为 dfx 的文件)。
比如下面的 dfx 文件:




A B C
1 =connect("dm").query("select NAME as CITY, STATEID as STATE from   CITIES") []
2 for A1 =dm.query("select * from STATES where   STATEID=?",A2.STATE)
3
if left(B2.ABBR,1)==arg1 >A2.STATE=B2.NAME
4

>B1=B1|A2
5 return B1


SPL 脚本思路:
循环遍历 CITIES 表记录,通过 CITIES. STATES 过滤 STATES 表,若 STATES. ABBR 首字母为参数 arg1,则将 STATES 表中的 NAME 值赋给 CITIES. STATE,并将 CITIES 表中的这条记录拼接到 B1 格中,最终返回 B1 格的结果集。
在这个网格文件中,需要从数据源 dm 中获取数据,同时使用了参数 arg1:

imagepng

数据源配置方法可以参考上面的示例,网格文件保存为 city.dfx,dfx 文件可以存放在应用项目类路径或 raqsoftConfig.xml 中配置的主目录下,当 dfx 文件比较多的时候,为了便于统一维护和管理,我们还可以将 dfx 文件放到 dfx 寻址路径中,寻址路径的配置方式如下:
在 raqsoftConfig.xml 文件的 < Esproc> 节点中,添加以下内容:



     

D:\\dfxFile 
	
<dfxPathList>       <dfxPath>D:\\dfxFiledfxPath>dfxPathList>

调用部分代码如下:

stringspl = "call city(?)"; 
	
stringspl = "call city(?)";

rset 方法中传参部分代码如下:

  cmd.Parameters.Add("arg1", OdbcType.VarChar).Value = "A"; 
	
  cmd.Parameters.Add("arg1", OdbcType.VarChar).Value = "A";

输出结果集部分代码如下:

 while (reader.Read())

            {

Console.Write(reader.GetString(0) + "\\t");

Console.WriteLine(reader.GetString(1) + "\\t");

                nCount++;

            } 
	
while (reader.Read())             { Console.Write(reader.GetString(0) + "\\t"); Console.WriteLine(reader.GetString(1) + "\\t");                 nCount++;             }

通过 call 调用 dfx 文件除了上面的写法,还可以在调用 dfx 时直接传参,如下:

stringspl = "call city('A')"; 
	
stringspl = "call city('A')";

执行结果:

imagepng

上述内容就是 C# 调用 SPL 脚本的常用方式了,想了解更多集算器应用集成用法的小伙伴儿可以去官网上的中查看

阅读(1839) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~