读书人

急 程序中在执行一段代码的时候数据库

发布时间: 2012-12-14 10:33:08 作者: rapoo

急,高手请进,!! 程序中在执行一段代码的时候数据库出现死锁,。
本帖最后由 mr_cheung 于 2011-10-23 21:47:54 编辑 C# 在查询某条数据时出现死锁,超时情况。
一下是查询数据库方法 C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace WindowsFormsApplication1
{
class DBHelpSQL
{
static string stsqlcon = "Data Source=10.2.103.10;Initial Catalog=Testhis;User ID=sa";
//static string stsqlcon = "Data Source=127.0.0.1;Initial Catalog=ErrorMechanismDB;User ID=sa;pwd=95688859";
static SqlConnection sqlcon = null;

#region 访问数据库- 服务方法

/// <summary>
/// 访问数据库-- 双向语句 (执行 Select 查询操作)
/// </summary>
/// <param name="strsqlTow"></param>
/// <returns></returns>
public static DataSet GetDateSet(string strsqlTow)
{

Open(); //连接串
//利用数据适配器将数据从数据库填充到DataSet中
SqlDataAdapter sda = new SqlDataAdapter(strsqlTow, sqlcon);
/// sda.SelectCommand.CommandTimeout = 3600;
DataSet ds = new DataSet();
//开始填充数据到ds中的表temp中
sda.Fill(ds, "temp");
Close();
return ds;
}
public static DataTable GetDateTable(string strsqlTow)
{
Open(); //连接串
DataTable DT = new DataTable();
SqlDataAdapter myCommand = new SqlDataAdapter(strsqlTow, sqlcon);

DataSet ds = new DataSet();
myCommand.Fill(ds);

DT = ds.Tables[0];
myCommand.Dispose();
ds.Dispose();
sqlcon.Close();
Close();


return DT;
}

/// <summary>
/// 访问数据库-- 单项语句方法(执行 Insert 、 Update 、Delete 语句)
/// </summary>
/// <param name="strsql">SQL拼接语句</param>
/// <returns>如果执行成功 返回-1</returns>
public static int ExecuteNonQuery(string strsql)
{
Open();//连接串
SqlCommand cb = new SqlCommand(strsql, sqlcon); //执行SQL语句
int i = cb.ExecuteNonQuery(); //执行语句并返回影响的行数
Close();
return i;
}
/// <summary>
/// 打开数据库
/// </summary>
/// <returns></returns>
private static void Open()
{
if (sqlcon == null)
{
sqlcon = new SqlConnection(stsqlcon); //如果链接对象是null 就先实例化一下对象
sqlcon.Open(); //打开数据库
}
else
{
if (sqlcon.State == ConnectionState.Broken || sqlcon.State == ConnectionState.Closed) //如果数据库连接后 处于中断状态 那么需要先断开数据库 再重新连接
{
sqlcon.Close();//先关闭数据库
sqlcon.Open(); //再打开数据库
}

}
}
/// <summary>
/// 关闭数据库方法(只需调用一下 既可 关闭数据库)
/// </summary>
private static void Close()
{
if (sqlcon != null)


{
//如果数据库连接状态处于 链接中断 或者是 打开状态 我们都进行强制关闭数据库连接
if (sqlcon.State == ConnectionState.Broken || sqlcon.State == ConnectionState.Open)
{
sqlcon.Close();//关闭数据库
}
}
}
/// <summary>
/// 查询所有的患者信息
/// </summary>
private void GetAllData()
{
//查询数据

}
#endregion
#region 执行存储过程方法

/// <summary>
/// 执行存储过程的单线方法,返回影响的行数
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>影响的行数</returns>
public static int RunIntProcedure(string storedProcName, IDataParameter[] parameters)
{
int result = 0;
//SqlConnection connection = new SqlConnection(strsqlcon);
try
{
Open();
SqlCommand command = BuildIntCommand(sqlcon, storedProcName, parameters);
result = command.ExecuteNonQuery();//返回执行影响行数
command.CommandType = CommandType.StoredProcedure;
//result = (int)command.Parameters["ReturnValue"].Value;//返回存储过程的返回值
}
finally
{
Close();
}


return result;
}


/// <summary>
/// 执行存储过程的双向方法
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <param name="tableName">DataSet结果中的表名</param>
/// <returns>DataSet</returns>
public static DataSet RunDatsetProcedure(string storedProcName, IDataParameter[] parameters)
{
DataSet dataSet = new DataSet();
Open();
SqlDataAdapter sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = BuildQueryCommand(sqlcon, storedProcName, parameters);
sqlDA.Fill(dataSet, "temp");
Close();
return dataSet;
}
#endregion
#region 存储过程服务方法

/// <summary>
/// 创建 SqlCommand 对象实例(用来返回一个整数值)
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlCommand 对象实例</returns>
private static SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);
command.Parameters.Add(new SqlParameter("ReturnValue",
SqlDbType.Int, 4, ParameterDirection.ReturnValue,
false, 0, 0, string.Empty, DataRowVersion.Default, null));
return command;
}



/// <summary>
/// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)
/// </summary>


/// <param name="connection">数据库连接</param>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlCommand</returns>
private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = new SqlCommand(storedProcName, connection);
command.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
return command;
}

#endregion



}
}




以下是SQL 代码
create table Vipinfo ---用户信息表
(
Uid int identity(1,1),
U_Vidvarchar (30)unique,
患者IDvarchar(14),
姓名varchar(10) not null,
性别varchar(6) not null,
出生日期 datetime not null,
身份证varchar(38),
会员卡号 varchar(30),
建档时间datetime default(getdate()) not null
CONSTRAINT [PK_U_Vid] PRIMARY KEY CLUSTERED (U_Vid,患者ID)ON [PRIMARY]
)

go
create table Vipexpense
(
Vidvarchar(30),
单据号varchar(30) not null,
消费类别varchar(10) not null,
金额decimal(18,2) not null,
积分decimal(18,2) not null,
经办人varchar(30) not null,
建档时间datetime default(getdate()) not null,
)
--创建外键约束
BEGIN TRANSACTION
alter table dbo.Vipexpense add constraint FK_Vipexpense_Vipinfo
foreign key (Vid)
references dbo.Vipinfo([U_Vid]) ON UPDATE CASCADE ON DELETE CASCADE


go
Create table Goodsinfo
(
Gid int primary key identity(00001,00001),
商品名称varchar(80) not null,
商品类型varchar(60) not null,
兑换积分decimal(18,2) not null,
供应商varchar(100) not null,
建档时间datetime default(getdate()) not null,
)
go
create table Pointsfor
(
Pid int primary key identity(001,001),
U_Vidvarchar(30) foreign key references Vipinfo(U_Vid),
上次积分decimal(18,2) not null,
Gid int foreign key references Goodsinfo(Gid),
数量 int not null,
所需积分decimal(18,2) not null,
兑换时间datetime default(getdate()) not null


)


现在的问题是为什么数据库会锁住?
[解决办法]
原因查出来了,是因为外键的约束引起,很奇怪,如果表中必须要有外键的约束请问该如何处理。
[解决办法]
string cardNum = ReaderCard.td;//获取卡号
int cnum=cardNum.IndexOf("\0",0);//截取字符串
string strsql1 = "select * from dbo.Vipinfo where U_Vid='" + cardNum.Substring(0,cnum) + "'";//再次截取
DataTable dt1= DBHelpSQL.GetDateTable(strsql1);
if (dt1.Rows.Count >= 1)
{
MessageBox.Show("此张会员卡信息已存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
else
{

string card = this.Txtbcardnum.Text = ReaderCard.td;
string strsql = "select 姓名,性别,出生日期,身份证号,患者id from B患者基本信息 where 患者id='" + card + "'";
DataTable dt = DBHelpSQL.GetDateTable(strsql);
TxtUname.Text = dt.Rows[0]["姓名"].ToString();//获取姓名
Cmbsex.Text = dt.Rows[0]["性别"].ToString();//获取患者性别
TxtbAge.Text = dt.Rows[0]["出生日期"].ToString();///获取患者年龄
Txtsfz.Text = dt.Rows[0]["身份证号"].ToString();///获取身份证号

/*使用Dataset 取值
// DataSet ds =DBHelpSQL.GetDateSet(strsql);
//// DataSet ds = new DataSet();
// foreach (DataRow col in ds.Tables[0].Rows) //set.Tables[0].Rows 找到指定表的所有行 0这里可以填表名
// {
// Console.WriteLine(col[0].ToString()); //col[0]这一行的索引是0单元格,也就是列,你只要在0这里填上你要输出的第几列就行了
// }





//MessageBox.Show("读卡功能正在完善,敬请期待!", "读卡提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);//读卡提示信息

*/
}


[解决办法]
引用:
原因查出来了,是因为外键的约束引起,很奇怪,如果表中必须要有外键的约束请问该如何处理。

谁告诉你表中必须要有外键的约束, 你老师? 还是你经理?

这个用程序控制就好了, 多余的约束会影响数据库性能
[解决办法]
完整的程序应该包括客户端数据校验,
和数据库操作后异常处理。

读书人网 >.NET

热点推荐