熟悉 VFP的朋友都知道,在 VFP 里我们可以使用远程视图 (Remote View) 和 SPT(SQL Pass Through) 技术控制远程异构数据库.这些技术其实是 VFP 对 ODBC 的 API 的封装,所以对于用户来说访问远程数据库就像操作传统的DBF一样简单.关于这两种技术的使用,完全可以洋洋洒洒地写下一本书,鉴于本文主题及篇幅,这里仅枚举 SPT 技术访问远程数据的应用.
很多人认为有了远程视图这样直观、简单的工具,为什么还需要 SPT 呢?确实 SPT 较远程视图难以掌握,但细细体会你会发现:远程视图其实是对 SPT 的可视化工具!SPT 较远程视图更具威力,远程视图提供的功能只是 SPT 的一个子集.其优势和劣势主要体现在以下几个方面:
l、SPT 的优势
①.) 一次得到多个Cursor;
①.) 没有图形用户界面;
下面就顺着我们对 SPT 的认识,来浏览一下这个伟大的工具吧!(注意:本文所有例程均使用 SQL Server的NorthWind 数据库演示).
管理连接
l、建立连接
注意:本文所有示例的代码若用到连接的,默认采用"建立连接"代码中产生的连接句柄 "CON".
WAIT ' 连接到 SQL Server 上去 ' NOWAIT NOCLEAR WINDOW
CON=SQLSTRINGCONNECT("driver=SQLServer;Server=BOE;Uid=sa;pwd=;database=northwind")
*假定 SQL Server 服务器名为 BOE, 用户 ID 是sa, 口令是空串
*如果你的 SQL Server 的服务器名, 用户 ID, 口令与上不同,请修改以上代码中的相关部分以符合你系统中的设置
WAIT clear
IF con=0
ELSE
ENDIF
SQLDISCONNECT(CON)
一次得到多个Cursor
我们可以用一次 SPT 传回多个Cursor,如下:
cSQL="SELECT * FROM EMPLOYEES"+CHR(10)+"SELECT * FROM CUSTOMERS"+CHR(10)+"SELECT * FROM PRODUCTS"
SQLEXEC(con,cSQL,"TEMP")
执行其他 SQL 语句
下面我们尝试执行SQL Server以外的SQL语句:
cSQL="IF EXISTS(SELECT * FROM CUSTOMERS where CUSTOMERID='TEST')"
cSQL=cSQL+" DELETE FROM CUSTOMERS where CUSTOMERID='TEST'"
cSQL=cSQL+" ELSE INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES('TEST',' 这是一个测试! ')"
IF SQLEXEC(CON,cSQL)=0
行文至此,也许有朋友会问:如果 SQL 语句中 CUSTOMERID 是一个变量怎么办呢?其实 我们可以通过两个常用的解决方案来解决:
①.、拼接字符串
CUSTID='TEST'
cSQL="IF EXISTS(SELECT * FROM CUSTOMERS where CUSTOMERID='"+CUSTID+"')"
cSQL=cSQL+" DELETE FROM CUSTOMERS where CUSTOMERID='"+CUSTID+"'"
cSQL=cSQL+" ELSE INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES('"+CUSTID+"',' 这是一个测试! ')"
SQLEXEC(CON,cSQL)
cSQL="IF EXISTS(SELECT * FROM CUSTOMERS where CUSTOMERID=?CUSTID)"
cSQL=cSQL+" DELETE FROM CUSTOMERS where CUSTOMERID=?CUSTID"
cSQL=cSQL+" ELSE INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES(?CUSTID,' 这是一个测试! ')"
特殊函数和命令
如果在 SQL Server 中你有足够的权限,通过 SPT 使用远程数据库的特殊函数和命令,你可以完全控制 SQL Server ,这里我们就演示"怎样取得数据库服务器的时间":
SQLEXEC(con,"select getdate() as serverdatetime","temp1")
temp1.serverdatetime
USE IN ("temp1")
事务管理
cSQL="DELETE FROM CUSTOMERS where CUSTOMERID='BLAUS'"+CHR(10)
cSQL=cSQL+"INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES('TEST1',' 这是一个测试! ')"
IRETURN=SQLEXEC(CON,cSQL)
IF IRETURN=1
SQLCOMMIT(CON) 事务交付
SQLROLLBACK(CON) 事务回滚
SQLSETPROP(CON,"Transactions" ,1) 重新回到自动事务处理状态
就本例而言,"DELETE FROM CUSTOMERS where CUSTOMERID='BLAUS'"总是不能执行的,SQL Server会返回出错揭示:
DELETE statement conflicted with COLUMN REFERENCE constraint 'FK_Orders_Customers'.
The conflict occurred in database 'Northwind', table 'Orders', column 'CustomerID'.
所以这笔事务总是被回滚的!!
从例程中可以看到,我们开启的事务其实是针对"连接"的,也就是说通过该"连接"的所有数据更新都包含于事务中,直到事务被回滚或交付.
用java连接数据库的话,先用ODBC创建数据源,然后在java源程序中加载驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
之后创建连接
String url = "jdbc:odbc:thename" //thename为创建的数据源名称
Connection con = DriverManager.getConnection(url);
之后定义 Statement st = con.createStatement();用于查询.
st.executeQuery(string sqlstring);//sqlstring 为sql语句.
这里附上自己做的登陆时由用户名查询密码的程序.希望能有帮助.
import java.sql.*;
public class sqlserver
{
static String data = "jdbc:odbc:chatroom";
static java.sql.Statement st;
public static void databaseconnect()
{ //函数用于 连接数据库
try
Connection conn = DriverManager.getConnection(data, "", "");
st = conn.createStatement();
}
catch (Exception e)
System.out.println("异常:"+e.toString());
public static String pwquery(String name)
{ //函数用于 密码查询,传入 用户名,返回密码
//此方法当用户名不存在时,返回空串,所以输入前先验证用户名是否为空
databaseconnect();
String inname = name;
String pw = "";
ResultSet rs=null;
rs = ((java.sql.Statement) st).executeQuery("select password from user_login where name='"+inname+"'");
while(rs.next())
pw=rs.getString("password");
rs.close();
st.close();
catch (SQLException e)
e.printStackTrace();
return pw;
代码在Eclipse中测试成功.并不需要插件
一个单引号,是最正常的情况,比如:'asdfas',这代表一个字符串,显示的内容是 asdfas ;
两个单引号,一般成对出现在一个单引号之内,表示一个单引号之内的单引号,比如
三个或四个单引号的情况是在一个和两个的情况之上发展出来的,比如'asd'''||输入值||'''',它显示的时候内容就是:
asd'输入值'.
(把一对两个单引号分开了,一部分在||之前,一部分在||之后)
(后面四个单引号分开看,中间两个是一对--代表一对单引号之内的一个单引号,外边两个是一对--代表一对单引号)
ISNULL
使用指定的替换值替换 NULL.
语法
ISNULL ( check_expression , replacement_value )
如果 check_expression 不为 NULL,那么返回该表达式的值;否则返回 replacement_value.
示例
A. 将 ISNULL 与 AVG 一起使用
下面的示例查找所有书的平均价格,用值 $10.00 替换 titles 表的 price 列中的所有 NULL 条目.
USE pubs
GO
SELECT AVG(ISNULL(price, $10.00))
FROM titles
下面是结果集:
--------------------------
(1 row(s) affected)
B. 使用 ISNULL
下面的示例为 titles 表中的所有书选择书名、类型及价格.如果一个书名的价格是 NULL,那么在结果集中显示的价格为 0.00.
ISNULL(price, 0.00) AS Price
Title Type Price
--------------- ------------ --------------------------
The Psychology UNDECIDED 0.00
Net Etiquette popular_comp 0.00
①.、首先需要创建数据库表t_user_info,利用创建表SQL语句create table.
isnull的作用是当RecIndex为null时,赋予空串,然后和空串比较,不相等.
is
not
null
and
@RecIndex
''