数据提供程序的Command类是IDBCommand接口的实现,通过Command来执行数据库命令,数据库数据的查询、更新、插入都通过Command来实现。
Command的构造函数通常都有下面三种形式:
1, public xxxCommand();
2, public xxxCommand(string);
3, public xxxCommand(string,xxxConnection);
一般我们创建Command对象都通过类似于下面的语句来实现:
xxxConnection conn = new xxxConnection("myString");
xxxCommand myCmd = new xxxCommand("select * from orders",conn);
构造函数的两个参数是SQL语句和Connection对象,创建了Command对象。

下面说明Command对象的执行,程序范例将采用SqlClient数据提供程序来访问一个Sql Server的数据库Northwind。

一、设置连接和SQL命令
Command类的属性CommandText用来设置命令语句,Connection属性用来设置连接对象。设置命令对象的数据连接和命令语句除了可以在通过创建对象时通过构造函数定义外,这两个属性设置和更改。
SqlConnection conn = new SqlConnection("Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
conn.Open();
SqlCommand cmd = new SqlCommand("select * from [Orders]",conn);
cmd.CommandText = "delete [Orders] where [OrderID]=10248";

二、执行命令
建立了数据源的连接和设置了命令之后,Command对象执行SQL命令有三种方法:ExecuteNonQuery、ExecuteReader和ExecuteScalar。
使用ExecuteNonQuery执行命令不会返回结果集,只会返回语句影响的记录行数,它适合执行插入、更新、删除之类不返回结果集的命令。如果是SELECT语句,那么返回的结果是-1,如果发生回滚这个结果也是-1。下面的程序范例对Orders表执行了更新并做了查询。

using System;
using System.Data;
using System.Data.SqlClient;
public class myDataAccess{
 public static void Main(){
  SqlConnection conn = new SqlConnection("Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
  SqlCommand cmd = new SqlCommand("update [Orders] set [OrderDate]='2004-9-1' where [OrderID]=10248",conn);
  try{
   conn.Open();
   int i = cmd.ExecuteNonQuery();
   Console.WriteLine(i.ToString() + " rows affected by UPDATE");
   cmd.CommandText = "select * from [Orders]";
   i = cmd.ExecuteNonQuery();
   Console.WriteLine(i.ToString() + " rows affected by SELECT");
  }
  catch(Exception ex){
   Console.WriteLine(ex.Message);
  }
  finally{
   conn.Close();
  }
 }
}

使用ExecuteReader方法执行的命令,可以返回一个类型化的DataReader实例或者IDataReader接口的结果集。通过DataReader对象就能够获得数据的行集合,本文不准备详细讨论DataReader,关于DataReader的使用将来再说明。下面是一个例子。
using System;
using System.Data;
using System.Data.SqlClient;
public class myDataAccess{
 public static void Main(){
  SqlConnection conn = new SqlConnection("Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
  SqlCommand cmd = new SqlCommand("select top 20 * from [Orders]",conn);
  SqlDataReader reader; //或者IDataReader reader;
  try{
   conn.Open();
   reader = cmd.ExecuteReader();
   while(reader.Read()){
    Console.WriteLine(reader[0].ToString());
   }
   reader.Close();
  }
  catch(Exception ex){
   Console.WriteLine(ex.Message);
  }
  finally{
   conn.Close();
  }
 }
}

对于ExecuteReader方法,如果想获得数据的记录行数,可以通过select count(*)这样的语句取得一个聚合的行集合。对于这样求单个值的语句,Command对象还有更有效率的方法——ExecuteScalar。它能够返回对应于第一行第一列的对象(System.Object),通常使用它来求聚合查询结果。需要注意的是,如果需要把返回结果转化成精确的类型,数据库在查询中就必须强制将返回的结果转换,否则引发异常。下面是例子:

using System;
using System.Data;
using System.Data.SqlClient;
public class myDataAccess{
 public static void Main(){
  SqlConnection conn = new SqlConnection("Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
  SqlCommand cmd = new SqlCommand("select count(*) from [Orders]",conn);
  try{
   conn.Open();
   int i = (int)cmd.ExecuteScalar();
   Console.WriteLine("record num : " + i.ToString());
   cmd.CommandText = "select cast(avg([Freight]) as int) from [Orders]";
   int avg = (int)cmd.ExecuteScalar();
   Console.WriteLine("avg : " + avg.ToString());
   cmd.CommandText = "select avg([Freight]) from [Orders]";
   avg = (int)cmd.ExecuteScalar(); //引发异常
   Console.WriteLine("avg : " + avg.ToString());
  }
  catch(Exception ex){
   Console.WriteLine(ex.Message);
  }
  finally{
   conn.Close();
  }
 }
}


这个程序中,最后一个查询将引发异常,因为聚合返回的结果是float类型的,无法转换。

三、参数化查询
参数化的查询能够对性能有一定的优化,因为带参数的SQL语句只需要被SQL执行引擎分析过一次。Command的Parameters能够为参数化查询设置参数值。Parameters是一个实现IDataParamterCollection接口的参数集合。
不同的数据提供程序的Command对参数传递的使用不太一样,其中SqlClient和OracleClient只支持SQL语句中命名参数而不支持问号占位符,必须使用命名参数,而OleDb和Odbc数据提供程序只支持问号占位符,不支持命名参数。
对于查询语句SqlClient必须使用命名参数,类似于下面的写法:
SELECT * FROM Customers WHERE CustomerID = @CustomerID --Oracle的命名参数前面不用@,使用(:),写为(:CustomerID)
而对于OleDb或者Odbc必须使用?占位符,类似于下面的写法:
SELECT * FROM Customers WHERE CustomerID = ?

下面以Sql Server为范例,说明其使用方法:
using System;
using System.Data;
using System.Data.SqlClient;
public class myDataAccess{
 public static void Main(String[] args){
  SqlConnection conn = new SqlConnection("Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
  SqlCommand cmd = new SqlCommand("select * from [Orders] where [OrderID]=@oid",conn);
  SqlDataReader reader;
  try{
   int param = Convert.ToInt32(args[0]);
   cmd.Parameters.Add("@oid",param);  //使用命名参数
   cmd.Parameters[0].Direction = ParameterDirection.Input;
   conn.Open();
   reader = cmd.ExecuteReader();
   while(reader.Read()){
    Console.WriteLine(reader[0].ToString());
   }
   reader.Close();
  }
  catch(Exception ex){
   Console.WriteLine(ex.Message);
  }
  finally{
   conn.Close();
  }
 }
}

对于OleDb或者Odbc数据提供程序的命令参数,只需要把参数按照占位符从左到右的顺序,匹配给Parameters集合就行了。 下面是程序范例:

using System;
using System.Data;
using System.Data.OleDb;
public class myDataAccess{
 public static void Main(String[] args){
  OleDbConnection conn = new OleDbConnection("Provider=SQLOLEDB;Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
  OleDbCommand cmd = new OleDbCommand("select * from [Orders] where [OrderID]=? or [EmployeeID]=?",conn);
  OleDbDataReader reader;
  try{
   int param1 = Convert.ToInt32(args[0]);
   int param2 = Convert.ToInt32(args[1]);
   cmd.Parameters.Add("aaa",param1);
   cmd.Parameters.Add("bbb",param2); //参数对象还需要名字,但是和查询语句中的参数名无关
   cmd.Parameters[0].Direction = ParameterDirection.Input;
   cmd.Parameters[1].Direction = ParameterDirection.Input;
   conn.Open();
   reader = cmd.ExecuteReader();
   while(reader.Read()){
    Console.WriteLine(reader[0].ToString());
   }
   reader.Close();
  }
  catch(Exception ex){
   Console.WriteLine(ex.Message);
  }
  finally{
   conn.Close();
  }
 }
}

四、执行存储过程
使用Command对象访问数据库的存储过程,需要指定CommandType属性,这是一个CommandType枚举类型,默认情况下CommandType表示CommandText命令为SQL批处理,CommandType.StoredProcedure值指定执行的命令是存储过程。类似于参数化查询,存储过程的参数也可以使用Parameters集合来设置,其中Parameter对象的Direction属性用于指示参数是只可输入、只可输出、双向还是存储过程返回值参数。
需要注意的是如果使用ExecuteReader返回存储过程的结果集,那么除非DataReader关闭,否则无法使用输出参数。下面是一个例子:
存储过程
---------------------------------------------
CREATE procedure myProTest (
 @orderID as int,
 @elyTitle as varchar(50) output
)
as
select @elyTitle=ely.Title from [Orders] o join [Employees] ely on ely.EmployeeID=o.EmployeeID where o.OrderID=@orderID
select * from [Orders] where OrderID=@orderID
return 1
---------------------------------------------

程序
---------------------------------------------
using System;
using System.Data;
using System.Data.SqlClient;
public class myDataAccess{
 public static void Main(){
  SqlConnection conn = new SqlConnection("Server=localhost;Database=Northwind;User ID=sa;PWD=sa");
  SqlCommand cmd = new SqlCommand("myProTest",conn);
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.Parameters.Add("@orderID",10252);
  cmd.Parameters.Add("@elyTitle",SqlDbType.VarChar,50);
  cmd.Parameters.Add("@return",SqlDbType.Int);
  cmd.Parameters[0].Direction = ParameterDirection.Input;
  cmd.Parameters[1].Direction = ParameterDirection.Output;
  cmd.Parameters[2].Direction = ParameterDirection.ReturnValue;
  SqlDataReader reader;
  try{
   conn.Open();
   Console.WriteLine("execute reader...");
   reader = cmd.ExecuteReader();
   Console.WriteLine("@orderID = {0}",cmd.Parameters[0].Value);
   Console.WriteLine("@elyTitle = {0}",cmd.Parameters[1].Value);
   Console.WriteLine("Return = {0}",cmd.Parameters[2].Value);
   Console.WriteLine("reader close...");
   reader.Close();
   Console.WriteLine("@orderID = {0}",cmd.Parameters[0].Value);
   Console.WriteLine("@elyTitle = {0}",cmd.Parameters[1].Value);
   Console.WriteLine("Return = {0}",cmd.Parameters[2].Value);
   Console.WriteLine("execute none query...");
   cmd.ExecuteNonQuery();
   Console.WriteLine("@orderID = {0}",cmd.Parameters[0].Value);
   Console.WriteLine("@elyTitle = {0}",cmd.Parameters[1].Value);
   Console.WriteLine("Return = {0}",cmd.Parameters[2].Value);
  }
  catch(Exception ex){
   Console.WriteLine(ex.Message);
  }
  finally{
   conn.Close();
  }
 }
}


和参数化查询一样,OleDb或者Odbc数据提供程序不支持存储过程的命名参数,需要把参数按照从左到右的顺序,匹配Parameters集合。

转载于:https://www.cnblogs.com/Flysir/archive/2006/01/30/324383.html

执行数据库命令Command对象——ADO.NET学习应用笔记之三相关推荐

  1. java 怎么执行数据库命令_java 调用命令 备份mysql数据库

    代码如下: 1  String command  =   " cmd /c C:/Program Files/MySQL/MySQL Server 5.0/bin>mysqldump ...

  2. linux执行数据库的命令,实验-shell执行数据库命令.TXT

    今天来复习一下在shell中如何登陆oracle,并执行脚本或命令. 我编了以下这个小程序,起名为test.txt用于修改表结构,并执行几条输出命令: #!/bin/sh sqlplus -s &qu ...

  3. java执行数据库命令行_java程序执行命令行,解锁数据库表

    有些表锁的时间长或其他原因,在plsql中不能解锁,只能用命令行解锁. 有些功能跨平台系统的交互偶尔会锁表,就需要自动解锁. 下面是解锁的代码: package com.lg.BreakOracleU ...

  4. ADO学习(三)Command 对象

    Command 对象 ADO Command 对象用于执行面向数据库的一次简单查询.此查询可执行诸如创建.添加.取回.删除或更新记录等动作.如果该查询用于取回数据,此数据将以一个 RecordSet  ...

  5. command对象和DataReader的学习

    DataReader的学习 DataReader对象是从数据源中读取只读的且只向前的数据流.它的特点是读取速度非常快,但需要手动编写代码来实现数据的处理工作. DataReader对象中数据的获得是通 ...

  6. ADO.NET常用对象详解之:Command对象

    1.Command对象概述   Command对象可以使用数据库命令直接与数据源进行通信.它的属性如下:   Name:Command对象的程序化名称.在代码中使用此名称来引用Command对象.   ...

  7. MongoDB学习笔记-06 数据库命令、固定集合、GridFS、javascript脚本

    介绍MongoDB支持的一些高级功能: 数据库命令 固定大小的集合 GridFS存储大文件 MongoDB对服务端JavaScript的支持 数据库命令 命令的原理 MongoDB中的命令其实是作为一 ...

  8. ADO.NET Command对象简介

    Command 对象简介 Command 对象最主要的工作是透过Connection 对象对数据源下达操作数据库的命令. 我们以下列语法产生Command 对象: Dim cmA As Command ...

  9. ADO.NET中COMMAND对象的ExecuteNonQuery、ExcuteReader和ExecuteScalar方法

    1.ExecuteNonQuery方法. 该方法执行更新操作,即与UPDATE.INSERT.DELETE等语句有关的操作,在这种情况下,返回值是命令影响的行数.对其他语句,如SET或CREATE,则 ...

  10. android 数据回传代码,安卓向.net core api传输图片,执行保存到数据库命令后返回400错误代码,用postman测试没有问题安卓程序不行...

    安卓向.net core api传输图片,执行保存到数据库命令后返回400错误代码,用postman测试没有问题安卓程序不行,其他api没有问题,在执行保存到数据库命令之前也没有问题.希望各位大佬可以 ...

最新文章

  1. fileupload控件在ajax中无法使用
  2. JSPatch defineProtocol 实现详解
  3. 利用redis写webshell
  4. hdu4609 3idiots 三角形计数 FFT
  5. 【LeetCode笔记】剑指 Offer 57- II. 和为 s 的连续正数序列(Java、滑动窗口、二刷)
  6. html自动跳转到另外页面,html从一个页面跳转至另一个html页面的子页面
  7. Ubuntu临时修改ip地址
  8. 码怪之程序员的日常语录
  9. sqli-labs 第八关盲注脚本
  10. MySQL 8.0 新特性之窗口函数
  11. 计算机C盘什么引用了,电脑老是显示c盘引用了一个不可用的位置 怎么处理
  12. 南大 东大 计算机谁厉害,南京这两所985高校号称“双姝”:南大文理强势,东大工科超群...
  13. 惠普HP Deskjet 1180c 打印机驱动
  14. TP5 封装 mongoDB
  15. Ajax 和 XML: 五种 Ajax 反模式(转载)
  16. java分析内存泄露工具_Eclipse Memory Analyzer(Java内存泄漏分析工具)
  17. MySQL探秘(八):InnoDB的事务
  18. 这里神一样的重庆,有神一样的建筑
  19. STM8L101 与 STM8S103区别
  20. jitter 如何优化网络_爱帮网络推广|如何选择符合企业要求的SEO优化公司?

热门文章

  1. mysql日期格式转换_MySQL日期格式转换
  2. c++ 结构体和类的区别
  3. python的序列类型包括_python基础之常用序列类型(字符串)
  4. y电容如何选型_到底什么是安规电容?有什么作用?一文彻底请明白
  5. iPython Notebook安装和初体验
  6. 用UIWebView加载本地图片和gif图
  7. HDU 3829 Cat VS Dog
  8. Asp.Net基础 - 6.Cookie + 7.Session原理
  9. mysql数据库学习——2,数据库的选定,创建,删除和变更
  10. 构建高性能.NET应用之配置高可用IIS服务器-第三篇 IIS中三个核心组件的讲解(上)...