#region 构造函数
/// <summary>
/// 默认构造函数
/// </summary>
public GAdoNet() : this("")
{
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="strConn">连接字符串</param>
public GAdoNet(string strConn)
{
ConnectionString = strConn;
}
#endregion #region 保护方法
/// <summary>
/// 执行 SQL 语句并返回受影响的行数
/// </summary>
/// <param name="strSql">SQL 语句</param>
/// <returns>影响的行数</returns>
protected int ExecuteNonQuery(string strSql)
{
int intRtn = -1;
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn); try
{
objConn.Open();
intRtn = objCmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
}
finally
{
objCmd.Dispose();
objConn.Dispose();
} return intRtn;
} /// <summary>
/// 执行 SQL 语句并返回受影响的行数
/// </summary>
/// <param name="strSql">存储过程名</param>
/// <param name="objCmdType">命令类型</param>
/// <param name="objParams">参数集合</param>
/// <returns>影响的行数</returns>
protected int ExecuteNonQuery(string strSql, CommandType objCmdType, params SqlParameter[] objParams)
{
int intRtn = -1;
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn);
objCmd.CommandType = objCmdType;
for (int i = 0; i < objParams.Length; i++)
{
objCmd.Parameters.Add(objParams[i]);
} try
{
objConn.Open();
intRtn = objCmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
}
finally
{
objCmd.Dispose();
objConn.Dispose();
} return intRtn;
} /// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。
/// </summary>
/// <param name="strSql">SQL 语句</param>
/// <returns>第一行的第一列的值</returns>
protected object ExecuteScalar(string strSql)
{
object objRtn = null;
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn); try
{
objConn.Open();
objRtn = objCmd.ExecuteScalar();
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
}
finally
{
objCmd.Dispose();
objConn.Dispose();
} return objRtn;
} /// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。
/// </summary>
/// <param name="strSql">存储过程名</param>
/// <param name="objCmdType">命令类型</param>
/// <param name="objParams">参数集合</param>
/// <returns>第一行的第一列的值</returns>
protected object ExecuteScalar(string strSql, CommandType objCmdType, params SqlParameter[] objParams)
{
object objRtn = null;
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn);
objCmd.CommandType = objCmdType;
for (int i = 0; i < objParams.Length; i++)
{
objCmd.Parameters.Add(objParams[i]);
} try
{
objConn.Open();
objRtn = objCmd.ExecuteScalar();
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
}
finally
{
objCmd.Dispose();
objConn.Dispose();
} return objRtn;
} /// <summary>
/// 返回 DataReader 对象
/// </summary>
/// <param name="strSql">SQL 语句</param>
/// <returns>DataReader 对象</returns>
protected SqlDataReader ExecuteReader(string strSql)
{
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn);
SqlDataReader objReader = null; try
{
objConn.Open();
objReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return objReader;
} /// <summary>
/// 返回 DataReader 对象
/// </summary>
/// <param name="strSql">存储过程名</param>
/// <param name="objCmdType">命令类型</param>
/// <param name="objParams">参数集合</param>
/// <returns>SqlDataReader</returns>
protected SqlDataReader ExecuteReader(string strSql, CommandType objCmdType, params SqlParameter[] objParams)
{
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn);
objCmd.CommandType = objCmdType;
for (int i = 0; i < objParams.Length; i++)
{
objCmd.Parameters.Add(objParams[i]);
} SqlDataReader objReader = null; try
{
objConn.Open();
objReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return objReader;
}
/// <summary>
/// 返回DataSet
/// </summary>
/// <param name="strSql">存储过程名</param>
/// <param name="strTableName">表名</param>
/// <param name="objCmdType">命令类型</param>
/// <param name="objParams">参数集合</param>
/// <returns>DataSet</returns>
protected DataSet ExecuteDataSet(string strSql, string strTableName,
CommandType objCmdType, params SqlParameter[] objParams)
{
objConn = new SqlConnection(ConnectionString);
objCmd = new SqlCommand(strSql, objConn);
objCmd.CommandType = objCmdType;
for (int i = 0; i < objParams.Length; i++)
{
objCmd.Parameters.Add(objParams[i]);
}
objAdapter = new SqlDataAdapter(objCmd); DataSet objDataSet = null; try
{
objConn.Open();
objDataSet = FillDataSet(objAdapter, strTableName);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
}
finally
{
objAdapter.Dispose();
objCmd.Dispose();
objConn.Dispose();
} return objDataSet;
} /// <summary>
/// 返回DataSet
/// </summary>
/// <param name="strSql">SQL语句</param>
/// <param name="strTableName">表名</param>
/// <returns>DataSet</returns>
protected DataSet ExecuteDataSet(string strSql, string strTableName)
{
objConn = new SqlConnection(ConnectionString);
objAdapter = new SqlDataAdapter(strSql, objConn); DataSet objDataSet = null; try
{
objConn.Open();
objDataSet = FillDataSet(objAdapter, strTableName);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
}
finally
{
objAdapter.Dispose();
objConn.Dispose();
} return objDataSet;
}
#endregion #region 私有方法
/// <summary>
/// 填充数据集
/// </summary>
/// <param name="objAdapter">SqlDataAdapter</param>
/// <param name="strTableName">表名</param>
/// <returns>DataSet</returns>
private DataSet FillDataSet(SqlDataAdapter objAdapter, string strTableName)
{
DataSet objDataSet = new DataSet(); try
{
objAdapter.Fill(objDataSet, strTableName); // 记录数
_intRecordCount = objDataSet.Tables[strTableName].Rows.Count;
// 页数
_intPageCount = 0;
// 页号
_intFirstPage = 0;
_intPreviousPage = 0;
_intNextPage = 0;
_intLastPage = 0; // 分页填充数据
if (_intRecordCount > 0 && _intPageSize > 0)
{
// 页数
_intPageCount = (int) Math.Ceiling(_intRecordCount * 1.0 / _intPageSize);
// 页号
_intFirstPage = 1;
_intPreviousPage = _intPageNo - 1;
_intNextPage = _intPageNo + 1;
_intLastPage = _intPageCount;
// 规范页号
_intPageNo = (_intPageNo > _intPageCount) ? _intPageCount : _intPageNo;
_intPreviousPage = (_intPreviousPage <= 0) ? 1 : _intPreviousPage;
_intNextPage = (_intNextPage > _intPageCount) ? _intPageCount : _intNextPage; objDataSet.Clear();
// 分页填充
objAdapter.Fill(objDataSet, (_intPageNo - 1) * _intPageSize, _intPageSize, strTableName);
}
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return objDataSet;
}
#endregion
}
}
2、选择数据库连接方式"OLEDBORA";"ORACLIENT";"SQLCLIENT";
3、写几个常用函数
CreateConnection( )
private int ExecSQL(string[] SQL)
private DataSet InitDataSetTableBySQL( string astrTableName,string astrSQL)
public int GetReturnIntBySQL(string astrSQL)
public double GetReturnDoubleBySQL(string astrSQL)
public string GetReturnStringBySQL(string astrSQL)
1.提供多种查询方式,不使用直接传递SQL语句。
2.存储过程可以单独作类封装,最好不混在这里
3.提供更新,删除的操作(最好制作生成SQL语句的类工长)
4.使操作可以应用到外部的Transcation操作中
另外,最好能把次类的功能缩小到只处理单表。这样就可以得到表的字段和类型,对于
构造SQL语句将有很大的帮助。
看一下这个吧:)
to: 513(513) 实际上,这是我从自己的ado封装类修改而成的一个新类,只是将底的实现,根据ado.net重新实现了一份,没有太多考虑其它的因素。对你提出的问题,有些地方我还不知道如果实现更好,还请多多指教。事实上,对存储过程的支持,也可以用来模仿构造sql,如insert into temo (id, name) valeus (@intId, @strName),使用这样的语句,再使用存储过程调用的方法,即可以构造sql了。,如果有更复杂的sql,还是要自己手写了。我是做web开发的,对asp/php比较熟,对asp/php中的mvc模式开发比较熟。用net是个人兴趣,也是因为工作需要。刚刚接触一个月左右的时间,很多东西还不熟悉,只要有时间,我会多来.net版转转的。
to: henryfan1(每天好心情(*_*)) 从网上找了些相关的资料,感觉很好,正准备down源码来看看。谢谢
Dim objConn = new SqlConnection(ConnectionString);
Dim myCommand As New SqlCommand(ProcedureName, objConn)
Dim i As Integer
Dim DS As New DataSet() myCommand.CommandType = CommandType.StoredProcedure
For i = 0 To myParamArray.Length - 1
myCommand.Parameters.Add(myParamArray(i))
Next
Try
Dim SDA As New SqlDataAdapter(myCommand)
SDA.Fill(DS, "myTable") SDA.Dispose()
SDA = Nothing
Catch (ex As System.Data.SqlClient.SqlException)
throw e;
Finally
myCommand.Dispose()
Set myCommand = Nothing
objConn.Dispose()
Set objConn = Nothing
End Try
Return DS.Tables("myTable")
End Function
从你的代码看,CommRS是类中的一个方法。找到一处错误:
Catch (ex As System.Data.SqlClient.SqlException)
throw e;
应为
Catch (ex As System.Data.SqlClient.SqlException)
Throw ex
吧?!
用.net一直在使用C#,对VB.Net的语法不熟,你自己再看看这样修改是否合适。
我觉得,无论使用C#,还是VB.Net,主要是学习.Net FrameWork,这样才能写出更好的程序。还有,面向对象的思想,及许多其它的知识是必不可少的。
扯远了,这样的论述太多,还是让别人来说明吧。
只能在连接打开是操作!不只到你怎么处理??
[C#]
public SqlDataReader ExecuteReader(
CommandBehavior behavior
);
CommandBehavior.CloseConnection
受 .NET Framework 精简版的支持。
在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。
这个做一个基础类,保留返回dataset等等的单纯执行sql语句的东东就行了
想听听你的意见,你觉得,分页不必要加,还是要加到另一外类中?或者,写到页面中(我觉得在页面中写不大好,虽然,datagrid具备了分页的功能)。
/// 删除记录
/// </summary>
/// <param name="intId">记录id</param>
/// <returns>影响的行数</returns>
public int Delete(int intId)
{
int intAffectRows = -1; strSql = "sp_SubjectDel"; SqlParameter objId = new SqlParameter("@intId", intId);
SqlParameter objAffectRows = new SqlParameter(); // Id
objId.Direction = ParameterDirection.Input;
objId.DbType = DbType.Int32; // AffectRows
objAffectRows.Direction = ParameterDirection.Output;
objAffectRows.ParameterName = "@intAffectRows";
objAffectRows.DbType = DbType.Int32; try
{
ExecuteNonQuery(strSql, CommandType.StoredProcedure,
objId ,objAffectRows); intAffectRows = Convert.ToInt32(objAffectRows.Value);
}
catch(System.Data.SqlClient.SqlException e)
{
throw e;
} return intAffectRows;
}
这是我的数据库操作类的一个方法,用来删除记录。调用的存储过程,一个输入参数,一个输出参数。为了完成一个网站后台,我才写的这个类,可以说,还是有一定的实用性的。发到这儿来,想听听大家的意见,把他写的更好。
........,,BB@@............++@@@@33..............33..................................................,,++....................,,33,,..........
........@@MM99......::99AA99@@@@99..............@@AAAA@@............................................++MMAA....................AABB::,,,,....
........,,AA::,,99@@99::33++..............,,3399MMAA++........................................,,++....AABB::33,,............::AAMMBB@@MMAA..
........++@@,,..++,,....33BB................++BBAA........................::99AA::............,,AA..,,MMMMMMMM99........33BBMMAA::,,99MMBB,,
......++AABB,,....++++..33AA................,,@@::33..................::BBMMMM99..............::MM..99MMMMMM99........33MMAA++..++@@99++,,..
......99::MM33::@@AABB,,++AA................AA::,,AA++@@................,,,,@@BB..............99AA..@@AA33BB::......,,MM@@..::AAMM@@........
....,,@@..339933@@++33..::BB..............33AA33@@MM@@BB....................BBMM++9999......,,BBAA..,,..33MMMMAA....,,MM33..33MMBB::AA++....
....,,@@......,,........++BB............,,BB,,33AABB@@,,..........,,,,,,::@@MMMMMMBB++......@@AA@@99....AABBAA99......++,,..,,MMMM++++++....
....++BB++..............++MM..........,,BB33....9999..............33BBMMMMMM99,,,,..........++,,AA@@....AA99AA::............,,MMMM@@........
....33MM33..............::MM,,........::99......AA::,,++............,,::++....................,,MM99....BB99@@33............33MMMMAA........
....33MM,,..............,,BB,,..................,,....@@99......................................99,,....BB99................++MMBBBBAA......
....::BB................++MM,,..........................BB++............................................AA99................@@MMBB@@99......
......,,..............,,AA99............................++::............................................::::..................::,,..........
http://www.aspxcn.com/dotnetbbs/View.aspx?fbId=17&Id=223661
指点不敢妆,共同讨论吧。
在我的类中共提供了经过重载的4个方法,一个是针对sql的,另外一个是针对存储过程的(也可以针对特殊的sql,在前面我已经举过例子了)。
我不明白你指的不会调用存储过程是什么意思?是在ado.net中不会调用,还是不清楚存储过程执行后,会得到什么样的结果。
我个人的感觉:调用存储过程主要是两方面,存储过程名和参数(in/out),只要你提供的方法可以实现多参数就可以了,而且,要让out类型的参数可以返回值。为了解决多参数的问题,我使用了C#中的params参数类型,就这样,我就是这样想的。
不知我是否说明了,我们可以继续讨论。
to: stpangpang(胖在一方)我写这个类,主要是为了实现一个公共的数据库操作,当时没有想太多。前面我已经说过了,最初是用asp+ado写的一个数据库操作类,使用.net后,又使用ado.net重写的类,当然,结构和方法都不同了,只保留了一些最初的想法。
我写的是一个抽象类,不能被实例化,要派生一个类后才能使用,这主要是基于我自己写程序的习惯考虑。主要是为了多个类使用相同的数据库连接,这样,就不必写重复的连接代码了。
我的开发结构是首先派生出一个子类,用来实现数据库连接。然后,再派生出子类的子类,基本上是一个表一个类。
静态方法我没有考虑过,在后面的修改中我会考虑加入的。
至于你提到的增删改操作,我实在不知道怎样才能写出一个通用的方法来,所以,只在ado.net基础之上提供了四个方法。我也看过一些网友写的增删改的方法,觉得并不是能用的方法,不知你是如何实现的?
我刚使用.net一个月左右的时间,刚刚起步,将代码发到这儿,就是想和大家交流一下,这样才能提高。
to: ddangerous169(零点烛光)我捕捉的异常也没有进行处理,只是又抛出而已。
在异常处理方法,我不大熟,只是习惯性的加上了try/catch/finally。还请有这方面经验的朋友指点。
to: cqnetboy(NetBoy) 1、这主要是基于个人习惯考虑的,不想这个类被实例化,只有派生出一个类后,才能进行相关的操作。这样,可以在这个类的基础上,构建出一个复杂的类图(这只是一个想法而已)。
2、我刚刚完成了一个网站的后台程序,下面就是我的举例代码。
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;using Gcs.Data;
using Gcs.String;namespace Hospital.Database
{
/// <summary>
/// 数据库连接
/// </summary>
public abstract class Hospital : GAdoNet
{
public Hospital() :
base(ConfigurationSettings.AppSettings["strConnection"])
{
}
}
}这针对一个表的封装类,派生自Hospital
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;using Gcs.Data;
using Gcs.String;namespace Hospital.Database
{
/// <summary>
/// 友情链接
/// </summary>
public class FriendLink : Hospital
{
private int m_intId;
private string m_strName;
private string m_strUrl;
private string m_strFileName;
private int m_intHeight;
private int m_intWidth; #region 公有属性, 对应表中字段
/// <summary>
/// ID
/// </summary>
public int ID
{
get
{
return m_intId;
}
} /// <summary>
/// 友情链接名称
/// </summary>
public string Name
{
get
{
return m_strName;
}
set
{
m_strName = value;
}
} /// <summary>
/// 友情链接地址
/// </summary>
public string Url
{
get
{
return m_strUrl;
}
set
{
m_strUrl = value;
}
} /// <summary>
/// 友情链接图片名称
/// </summary>
public string FileName
{
get
{
return m_strFileName;
}
set
{
m_strFileName = value;
}
} /// <summary>
/// 友情链接图片高度
/// </summary>
public int Height
{
get
{
return m_intHeight;
}
set
{
m_intHeight = value;
}
} /// <summary>
/// 友情链接图片宽度
/// </summary>
public int Width
{
get
{
return m_intWidth;
}
set
{
m_intWidth = value;
}
}
#endregion public FriendLink() : base()
{
} /// <summary>
/// 添加记录
/// </summary>
/// <returns>新标识</returns>
public int AddNew()
{
int intNewId = -1; strSql = "INSERT INTO FriendLink"
+ " (Name, Url, FileName, Height, Width) VALUES"
+ " (@strName, @strUrl, @strFileName, @intHeight, @intWidth)"
+ " SELECT @@IDENTITY"; SqlParameter objName = new SqlParameter("@strName", Name);
SqlParameter objUrl = new SqlParameter("@strUrl", Url);
SqlParameter objFileName = new SqlParameter("@strFileName", FileName);
SqlParameter objHeight = new SqlParameter("@intHeight", Height);
SqlParameter objWidth = new SqlParameter("@intWidth", Width); // Name
objName.Direction = ParameterDirection.Input;
objName.DbType = DbType.String; // Url
objUrl.Direction = ParameterDirection.Input;
objUrl.DbType = DbType.String; // FileName
objFileName.Direction = ParameterDirection.Input;
objFileName.DbType = DbType.String; // Height
objHeight.Direction = ParameterDirection.Input;
objHeight.DbType = DbType.Int32; // Width
objWidth.Direction = ParameterDirection.Input;
objWidth.DbType = DbType.Int32; try
{
object objId = ExecuteScalar(strSql, CommandType.Text,
objName, objUrl, objFileName, objHeight, objWidth); intNewId = (objId == null) ? -1 : Convert.ToInt32(objId);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return intNewId;
} /// <summary>
/// 删除记录
/// </summary>
/// <param name="id">标识</param>
/// <returns>影响的行数</returns>
public int Delete(int id)
{
int intRtn = -1;
strSql = "DELETE FriendLink WHERE id=" + id; try
{
intRtn = ExecuteNonQuery(strSql);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return intRtn;
} /// <summary>
/// 记录列表
/// 使用后, 请关闭 SqlDataReader
/// </summary>
/// <returns>SqlDataReader</returns>
public SqlDataReader Browse()
{
SqlDataReader objReader = null;
strSql = "SELECT * FROM FriendLink ORDER BY id"; try
{
objReader = ExecuteReader(strSql);
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return objReader;
} /// <summary>
/// 查看记录信息
/// </summary>
/// <param name="intId">记录id</param>
/// <returns>true or false</returns>
public bool View(int intId)
{
bool blnRtn = false;
strSql = "SELECT * FROM FriendLink WHERE id = " + intId; try
{
SqlDataReader objReader = ExecuteReader(strSql); if (objReader.Read())
{
blnRtn = true; m_intId = intId;
Name = objReader.GetString(objReader.GetOrdinal("Name"));
Url = objReader.GetString(objReader.GetOrdinal("Url"));
FileName = objReader.GetString(objReader.GetOrdinal("FileName"));
Height = objReader.GetInt32(objReader.GetOrdinal("Height"));
Width = objReader.GetInt32(objReader.GetOrdinal("Width"));
} objReader.Close();
}
catch (System.Data.SqlClient.SqlException e)
{
throw e;
} return blnRtn;
} }
}由于篇幅的限制,我只挑选了几个方法,希望能说明我的数据库操作类的使用。
感谢大家关注我的帖子,请大家继续提意见!
今天再看看,我感觉我们的意思差不多~ 我写的增删改就是你的重载的ExecuteNonQuery方法不过是静态的,
我有一个建议,在执行一些方法(传入sql语句)之前,先剔除一些非法字符~
目前这个类只是自己使用,一些问题都在派生类中注意了,谢谢你的建议!
}
2 : 建议写一个带有事物的方法 参数是一个 strsql 数组
因为现在的一些操作,要同时网好几个表中写数据,如果光用 int ExecuteNonQuery(string strSql) 方法的话,不好实现数据回滚,得自己写事物。
这个正在考虑,测试,等完成了,请你指正一下3;看了你的执行存储过程的一些方法
我的想法是,既然是存储过程,就直接设定cmd.CommandType, 减少出错的几率4;如果客户端经常的访问数据库,这样写,服务器的开销大吗?建立连接开销比较大,我的想法是连接设置成static,或者使用缓冲池?to: stpangpang(胖在一方)1、一般情况下,我都是使用ExecuteScalar来完成类似的功能,sql可以这样写select count(*) from TableName where condition,ExecuteScalar返回的是表第一行第一列的值。2、我的程序中很少用到事务,而且,多半都是在存储过程中使用事务。所以,没有考虑到这方面的问题,先看看你的实现,向你学习。3、你看一下我前面的帖子,其实,执行存储过程的语句,还可以用来执行特殊的sql,如:insert into temo (id, name) valeus (@intId, @strName)。最初我只是用来执行存储过程,后来又改成现在的方式的,因为我觉得这样更方便。我在考虑,是否再添加一个重载的方法,专用执行存储过程,这样就更方便了。4、我看ado.net中提到,连接池可以由ConnectionString的设置实现,只是我在web的实现上还没有感觉到有什么好处。我正想问这方面的问题呢。
我的这段代码,还不完善,并没有发挥ado.net的优点,比如对dataset的使用等。我正学习,随着学习的深入,我会不断的修改代码,而且,经过修改的代码,都会在公司的项目中使用的。
objFriend.PageNo = 1;
objFriend.Browse();这样产生的DataSet就是经过分页的数据了。objFriend.PageNo是页号,PageSize是页大小。这个方面还存在一些问题,当用户选择分页时(PageSize > 0),我Fill了两次DataSet,这肯定会影响速度。而且,我还想对SqlDataReader进行分页,由于这次公司的项目不用对SqlDataReader进行分页,而且,我还没有找到更好的办法,所以没有实现。
前面也有网友提到了,是否有必要进行分页的问题。在这个问题方面,我比较倾向于完成类似的代码。欢迎各位继续发表意见,如果能更好的解决方案最好。谢谢各位关注。
CREATE PROCEDURE sp_GetEmployeesByPage
@PageNumber int,
@PageSize int
ASCREATE TABLE #Temp
(
ID int IDENTITY PRIMARY KEY,
EmployeeID int,
LastName nvarchar(20),
FirstName nvarchar(10),
Title nvarchar(30),
TitleOfCourtesy nvarchar(25),
Address nvarchar(60),
City nvarchar(15),
Region nvarchar(15),
Country nvarchar(15),
Notes ntext
)INSERT INTO #Temp
(
EmployeeID,
LastName,
FirstName,
Title,
TitleOfCourtesy,
Address,
City,
Region,
Country,
Notes
)
SELECT
EmployeeID,
LastName,
FirstName,
Title,
TitleOfCourtesy,
Address,
City,
Region,
Country,
Notes
FROM
Employees ORDER BY EmployeeID ASCDECLARE @FromID int
DECLARE @ToID intSET @FromID = ((@PageNumber - 1) * @PageSize) + 1
SET @ToID = @PageNumber * @PageSize-- select the page of records
SELECT * FROM #Temp WHERE ID >= @FromID AND ID <= @ToID
GO-------调用
SqlCommand cmd = new SqlCommand("sp_GetEmployeesByPage", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@PageNumber", SqlDbType.Int, 4));
cmd.Parameters["@PageNumber"].Value = Datagrid1.CurrentPageIndex + 1;
cmd.Parameters.Add(new SqlParameter("@PageSize", SqlDbType.Int, 4));
cmd.Parameters["@PageSize"].Value = Datagrid1.PageSize;
// open the connection and get the Reader
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
// bind the reader to the DataList
Datagrid1.DataSource = reader;
Datagrid1.DataBind();
用 if exists(select * from table where condition) insert into ....else ....
写一个存储过程,有返回值的,但是水平不够,没有研究. 有时间讨论一下
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Collections;namespace PetShop.Components {
public abstract class Database {
public static readonly string CONN_STRING = ConfigurationSettings.AppSettings["ConnString"];
private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable()); public static int ExecuteNonQuery(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString)) {
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
} public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
} public static SqlDataReader ExecuteReader(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connString); try {
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch {
conn.Close();
throw;
}
}
public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString)) {
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
} public static void CacheParameters(string cacheKey, params SqlParameter[] cmdParms) {
parmCache[cacheKey] = cmdParms;
} public static SqlParameter[] GetCachedParameters(string cacheKey) {
SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];
if (cachedParms == null)
return null;
SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length]; for (int i = 0, j = cachedParms.Length; i < j; i++)
clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone(); return clonedParms;
} private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {
if (conn.State != ConnectionState.Open)
conn.Open(); cmd.Connection = conn;
cmd.CommandText = cmdText; if (trans != null)
cmd.Transaction = trans; cmd.CommandType = cmdType; if (cmdParms != null) {
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
}
}
我的意思是:如果可以使用一个存储过程实现通用的分页操作,可是,由于表结构不同、返回结果集方法不同(视图、表、存储过程都可以返回结构集),这样一个存储过程不易实现。不知哪位高手有解决方案。昨天完成了手中的项目,看了一下Microsoft.ApplicationBlocks.Data的源码,很有收获,正准备对GAdoNet进行一些修改。
感谢各位关注这个帖子,请继续发表意见。