用SqlDataAdapterUpdateDataSetDs更新数据库Word格式.docx
- 文档编号:21056110
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:8
- 大小:19.46KB
用SqlDataAdapterUpdateDataSetDs更新数据库Word格式.docx
《用SqlDataAdapterUpdateDataSetDs更新数据库Word格式.docx》由会员分享,可在线阅读,更多相关《用SqlDataAdapterUpdateDataSetDs更新数据库Word格式.docx(8页珍藏版)》请在冰豆网上搜索。
否则会对后面用到的ds出现意想不到的错误。
郁闷~改了一天的程序,才发现是这个错误,太郁闷了~~
2.SqlCommandBuilder会自动生成更新、修改、删除的sql语句,进行更新。
3.当表中没有主键时,自动生成的SQL语句进行UPDate时,会出现异常信息。
异常信息为:
用SqlCommandBuilder更新DataSet,遇到“对于不返回任何键列信息的SelectCommand不支
持UpdateCommand的动态SQL生成”问题。
4.解决办法:
1.
修改表的定义,定义一个主键;
2.
为SqlDataAdapter指定UpdateCommand(DeleteCommand,InsertCommand应该也一样);
例子:
1.stringemailSql="
selectemail,validFlagfromemailMe"
;
DataSetemailAdd=newDataSet();
SqlDataAdapteremailAdapter=newSqlDataAdapter(emailSql,myConn);
SqlCommandBuildercb=newSqlCommandBuilder(emailAdapter);
emailAdapter.Fill(emailAdd,"
address"
);
myConn.Close();
DataTablemyDt=emailAdd.Tables["
];
myDt.PrimaryKey=newDataColumn[]{myDt.Columns["
email"
]};
......//修改myDs数据
emailAdapter.Update(emailAdd,"
自动生成SQL语句。
2.
stringemailSql="
SqlCommandupCmd=newSqlCommand("
update["
+strTableName+"
]setvalidFlag=@validFlagwhere
email=@email"
myConn);
upCmd.Parameters.Add("
@validFlag"
SqlDbType.Int,8,"
validFlag"
@email"
SqlDbType.NVarChar,100,"
emailAdapter.UpdateCommand=upCmd;
自定义SQL语句。
二.检索“标识”或“自动编号”值
检索“标识”或“自动编号”值
此页面仅适用于
MicrosoftVisualStudio2005/.NETFramework2.0
同时提供下列产品的其他版本:
*MicrosoftVisualStudio2008/.NETFramework3.5
.NETFramework开发人员指南
为了确保表中的每一行都有唯一的值,可以将DataTable中的列设置为自动递增的主键。
但是,您的应用程
序可能会有多个客户端,而每个客户端都可能会使用一个单独的DataTable实例。
在这种情况下,单独的
DataTable实例之间最终可能会出现重复的值。
由于所有客户端都使用单个数据源,因此可以让数据源定义自
动递增值,从而解决这一冲突。
若要完成此任务,请使用MicrosoftSQLServer中的“标识”列或
MicrosoftAccess中的“自动编号”字段。
如果使用数据源为添加到DataSet中的新行填充“标识”或“自动编号”列,则会出现唯一的情况,因为
DataSet与数据源之间没有直接连接。
因此,DataSet不识别任何由数据源自动生成的值。
但是,对于可以创
建带有输出参数的存储过程的数据源(如MicrosoftSQLServer),可以将自动生成的值(如新的标识值)
指定为输出参数并使用DataAdapter将该值映射回DataSet中的相应列。
数据源可能不支持带有输出参数的存储过程。
在这种情况下,将可以使用RowUpdated事件来检索自动生成的
值,并将其放入DataSet中的插入行或更新行。
本节包含一个示例,显示当在MicrosoftAccess2000或更
高版本上使用Jet4.0OLEDB提供程序时,如何将代码添加到RowUpdated事件中以确定插入是否已发生,
然后检索自动生成的值并将其存储在当前更新的行中。
检索SQLServer“标识”列的值
以下存储过程和代码示例显示如何将自动递增的标识值从MicrosoftSQLServer表映射回添加到向DataSet
的表添加的行中的相应列。
该存储过程用于将一个新行插入Northwind数据库的Categories表并以输出参
数的形式返回从Transact-SQLSCOPE_IDENTITY()函数返回的标识值。
CREATEPROCEDUREInsertCategory
@CategoryNamenchar(15),
@IdentityintOUT
AS
INSERTINTOCategories(CategoryName)VALUES(@CategoryName)
SET@Identity=SCOPE_IDENTITY()
InsertCategory存储过程可以指定为InsertCommand的源。
为接收“标识”输出参数创建一个参数。
该参数
具有Output的ParameterDirection,并将SourceColumn指定为DataSet中本地Categories表的
CategoryID列。
为添加的行处理InsertCommand后,将自动递增的标识值作为此输出参数返回,然后放入当
前行的CategoryID列中。
以下代码示例显示如何以输出参数的形式返回自动递增的值并将其指定为DataSet中CategoryID列的源值
。
C#
//AssumesthatconnectionisavalidSqlConnectionobject.
SqlDataAdapteradapter=newSqlDataAdapter(
"
SELECTCategoryID,CategoryNameFROMdbo.Categories"
connection);
adapter.InsertCommand=newSqlCommand("
InsertCategory"
adapter.InsertCommand.CommandType=CommandType.StoredProcedure;
adapter.InsertCommand.Parameters.Add(
@CategoryName"
SqlDbType.NChar,15,"
CategoryName"
SqlParameterparameter=adapter.InsertCommand.Parameters.Add(
@Identity"
SqlDbType.Int,0,"
CategoryID"
parameter.Direction=ParameterDirection.Output;
connection.Open();
DataSetcategories=newDataSet();
adapter.Fill(categories,"
Categories"
DataRownewRow=categories.Tables["
].NewRow();
newRow["
]="
NewCategory"
categories.Tables["
].Rows.Add(newRow);
adapter.Update(categories,"
connection.Close();
检索MicrosoftAccess“自动编号”值
MicrosoftAccess不支持存储过程或批命令处理,因此无法将输出参数映射到上例所示表中的源列。
但是,
MicrosoftAccess2000或更高版本支持@@IDENTITY属性在“插入”(INSERT)后检索“自动编号”字段的
值。
使用RowUpdated事件,您可以确定“插入”(INSERT)是否已发生,检索最新的“自动编号”值,然后
将该值放入DataSet中本地表的“标识”列。
以下代码示例显示如何使用OleDbDataAdapter将一个新值插入MicrosoftAccess2000Northwind数据库
的Categories表中。
该示例使用RowUpdated事件来填充在向Categories表中插入记录时Jet引擎和
Access数据库所生成的“自动编号”值。
请注意,这仅适用于Jet4.0OLEDB提供程序和Microsoft
Access2000或更高版本。
//AssumesthatconnectionisavalidOleDbConnectionobject.
OleDbDataAdapteradapter=newOleDbDataAdapter(
SELECTCategoryID,CategoryNameFROMCategoriesORDERBYCategoryID"
connection);
adapter.InsertCommand=newOleDbCommand(
INSERTINTOCategories(CategoryName)Values(?
)"
adapter.InsertCommand.CommandType=CommandType.Text;
adapter.InsertCommand.Parameters.Add(_
OleDbType.Char,15,"
//FilltheDataSet.
//Addanewrow.
//IncludeaneventtofillintheAutonumbervalue.
adapter.RowUpdated+=newOleDbRowUpdatedEventHandler(OnRowUpdated);
//UpdatetheDataSet.
//EventprocedureforOnRowUpdated
protectedstaticvoidOnRowUpdated(
objectsender,OleDbRowUpdatedEventArgsargs)
{
//IncludeavariableandacommandtoretrievetheidentityvaluefromtheAccessdatabase.
intnewID=0;
OleDbCommandidCMD=newOleDbCommand(
SELECT@@IDENTITY"
if(args.StatementType==StatementType.Insert)
//RetrievetheidentityvalueandstoreitintheCategoryIDcolumn.
newID=(int)idCMD.ExecuteScalar();
args.Row["
]=newID;
}
三.使用DataAdapter和DataSet更新数据库[C#]
DataAdapter的Update方法可调用来将DataSet中的更改解析回数据源。
与Fill方法类似,Update方法
将DataSet的实例和可选的DataTable对象或DataTable名称用作参数。
DataSet实例是包含已作出的更
改的DataSet,而DataTable标识从其中检索更改的表。
当调用Update方法时,DataAdapter将分析已作出的更改并执行相应的命令(INSERT、UPDATE或DELETE)
当DataAdapter遇到对DataRow的更改时,它将使用InsertCommand、UpdateCommand或DeleteCommand
来处理该更改。
这样,您就可以通过在设计时指定命令语法并在可能时通过使用存储过程来尽量提高ADO.NET
应用程序的性能。
如果调用了Update但不存在用于特定更新
的相应命令(例如,不存在用于已删除行的DeleteCommand),则将引发异常。
Command参数可用于为DataSet中每个已修改行的SQL语句或存储过程指定输入和输出值。
有关更多信息,
请参阅将参数用于DataAdapter。
如果DataTable映射到单个数据库表或从单个数据库表生成,则可以利用CommandBuilder对象自动生成
DataAdapter的DeleteCommand、InsertCommand和UpdateCommand。
有关更多信息,请参阅自动生成的命令
Update方法会将更改解析回数据源,但是自上次填充DataSet以来,其他客户端可能已修改了数据源中的数
据。
若要使用当前数据刷新DataSet,请再次使用DataAdapter填充(Fill)DataSet。
新行将添加到该表中
,更新的信息将并入现有行。
若要处理可能在Update操作过程中发生的异常,可以使用RowUpdated事件在这些异常发生时响应行更新错
误(请参阅使用DataAdapter事件),或者可以在调用Update之前将
DataAdapter.ContinueUpdateOnError设置为true,然后在Update完成时响应存储在特定行的RowError
属性中的错误信息(请参阅添加和读取行错误信息)。
注意如果对DataSet、DataTable或DataRow调用AcceptChanges,则将使某DataRow的所有Original
值被该DataRow的Current值改写。
如果已修改将该行标识为唯一行的字段值,那么当调用AcceptChanges
后,Original值将不再匹配数据源中的值。
以下示例演示如何通过显式设置DataAdapter的UpdateCommand来执行对已修改行的更新。
请注意,在
UPDATE语句的WHERE子句中指定的参数设置为使用SourceColumn的Original值。
这一点很重要,因为
Current值可能已被修改,并且可能不匹配数据源中的值。
Original值是曾用来从数据源填充DataTable的
SqlClient
[C#]
SqlDataAdaptercatDA=newSqlDataAdapter("
SELECTCategoryID,CategoryNameFROMCategories"
nwindConn);
catDA.UpdateCommand=newSqlCommand("
UPDATECategoriesSETCategoryName=@CategoryName"
+
WHERECategoryID=@CategoryID"
nwindConn);
catDA.UpdateCommand.Parameters.Add("
SqlDbType.NVarChar,15,"
SqlParameterworkParm=catDA.UpdateCommand.Parameters.Add("
@CategoryID"
SqlDbType.Int);
workParm.SourceColumn="
workParm.SourceVersion=DataRowVersion.Original;
DataSetcatDS=newDataSet();
catDA.Fill(catDS,"
DataRowcRow=catDS.Tables["
].Rows[0];
cRow["
catDA.Update(catDS);
OleDb
OleDbDataAdaptercatDA=newOleDbDataAdapter("
catDA.UpdateCommand=newOleDbCommand("
UPDATECategoriesSETCategoryName=?
"
WHERECategoryID=?
OleDbType.VarChar,15,"
OleDbParameterworkParm=catDA.UpdateCommand.Parameters.Add("
OleDbType.Integer);
自动递增列
如果来自数据源的表包含自动递增列,则可以使用由数据源生成的值填充DataSet中的列,方法是通过以存
储过程输出参数的形式返回自动递增值并将其映射到表中的一列,或者使用DataAdapter的RowUpdated事
件。
有关示例,请
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SqlDataAdapterUpdateDataSetDs 更新 数据库