• 转:获得数据库自增长ID(ACCESS)与(SQLSERVER)


    转载自:http://www.cnblogs.com/chinahnzl/articles/968649.html

    问题
    CSDN 里面不时有初学者疑惑:如何获取自增长列(标识列)的ID,并写入另一张表。
    场景
    这里选择典型的多对多关系,并以常见的 User-Role 作为 Demo,同时显示 Access 和 Sql Server 版本
    关系图

    实现要点
    1, 如何获取新插入记录生成的 ID:Sql Server 和 Access(当使用 Jet ADO,当然包括ADO.NET,连接时)均支持 @@Identity 全局变量,返回在当前会话的所有表中生成的最后一个标识值
    2,同时写入多张表需要显示使用事务

    MS Access 版本

    @@identity是表示的是最近一次向具有identity属性(即自增列)的表插入数据时对应的自增列的值,是系统定义的全局变量。一般系统定义的全局变量都是以@@开头,用户自定义变量以@开头。比如有个表A,它的自增列是id,当向A表插入一行数据后,如果插入数据后自增列的值自动增加至101,则通过select @@identity得到的值就是101。使用@@identity的前提是在进行insert操作后,执行select @@identity的时候连接没有关闭,否则得到的将是NULL值。

    INSERT INTO table(field1,field2,...) VALUES("field1Value","field2Value",...) SELECT IDENT_CURRENT('recordID') as newIDValue
    INSERT INTO table(field1,field2,...) VALUES("field1Value","field2Value",...) SELECT SCOPE_IDENTITY() as newIDValue
    INSERT INTO table(field1,field2,...) VALUES("field1Value","field2Value",...) SELECT @@IDENTITY as newIDValue 

    ACCESS中的@@IDENTITY由于ACCESS不允许使用“;”来分隔多条SQL语句进行执行,并且在执行两次OleDbCommand时后一个SELECT与前一个INSERT已经没什么关系了,所以在这使用 "select @@identity from [表名] " 将会得到的值为 0,这并不是我们所想得到的值,所以在ACCESS中如果想要得到 @@identity 的值,就可以使用事务来进行解决:

    /// <summary>
    /// 执行事务获取最新的ID
    /// </summary>
    /// <param name="cmdText"></param>
    /// <returns></returns>
    public int GetIdentity(string cmdText)
    {
        using (OleDbConnection oleCon = new OleDbConnection(connectionString))
        {
              oleCon.Open();
              OleDbCommand cmd = new OleDbCommand();//创建一个cmd
              OleDbTransaction trans = oleCon.BeginTransaction();//创建事务
                cmd.Connection = oleCon;//cmd连接
                cmd.Transaction = trans;//cmd的事务
                try
              {
                     cmd.CommandText = cmdText;//执行的SQL语句
                        cmd.ExecuteNonQuery();//执行insert 语句
                        cmd.CommandText = "select @@identity from [表名] ";//执行SQL,获取新增ID
                     trans.Commit();//提交事务
                        int i = Convert.ToInt32(cmd.ExecuteScalar());//执行Select @@identity 语句,获取id值
                        return i;//将Id值返回
                }
              catch
              {
                     trans.Rollback();//如果发生异常,回滚事务
                        return -1;//返回-1
              }
              finally
              {
                     oleCon.Close();//关闭数据源
                }
        }
    }
      1 <%@ Page Language="C#" %>
      2 <%@ Import Namespace="System.Data" %>
      3 <%@ Import Namespace="System.Data.OleDb" %>
      4 
      5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      6 
      7 <script runat="server">
      8 
      9     string connStr;
     10 
     11     protected void Page_Load(object sender, EventArgs e)
     12     {
     13         connStr = "provider=Microsoft.Jet.OleDb.4.0;data source=" + Server.MapPath("~/App_Data/DemoManyToMany.mdb");
     14     }
     15     
     16     protected void btnLogin_Click(object sender, EventArgs e)
     17     {
     18         if (chkRoles.SelectedIndex == -1) throw new Exception("至少选择一个角色。");        
     19         
     20         string sqlInserUser = "INSERT INTO [User]([UserName], [Password]) VALUES(?, ?)";
     21         string sqlInserUserRoel = "INSERT INTO UserRole([UserId], [RoleId]) VALUES(?, ?)";
     22         string sqlSelectNewUserId = "SELECT @@Identity"; // OR "SELECT MAX([UserId]) FROM [User]";
     23         using (OleDbConnection conn = new OleDbConnection(connStr)) {            
     24             conn.Open();
     25             // 显示开启事务
     26             OleDbTransaction trans = conn.BeginTransaction();            
     27             OleDbCommand cmd = conn.CreateCommand();
     28             // 关联事务
     29             cmd.Transaction = trans;           
     30             
     31             try {
     32                 cmd.CommandText = sqlInserUser;
     33                 cmd.Parameters.Add("UserName", txtUserName.Text);
     34                 cmd.Parameters.Add("Password", txtPassword.Text);
     35                 // 插入 User
     36                 cmd.ExecuteNonQuery();                               
     37 
     38                 cmd.CommandText = sqlSelectNewUserId;
     39                 // 读取新插入 UserId
     40                 int newUserId = (int)cmd.ExecuteScalar();
     41 
     42                 // 仅供测试
     43                 if (chkGeneratError.Checked) throw new Exception("创建用户时发生错误。");
     44 
     45                 cmd.CommandText = sqlInserUserRoel;
     46                 cmd.Parameters.Clear();
     47                 cmd.Parameters.Add("UserId", OleDbType.Integer);
     48                 cmd.Parameters.Add("RoleId", OleDbType.Integer);
     49                 cmd.Parameters[0].Value = newUserId;
     50                 // 遍历可选角色列表
     51                 foreach (ListItem item in chkRoles.Items) {
     52                     if (item.Selected) {
     53                         cmd.Parameters[1].Value = item.Value;
     54                         // 写入中间关系表 UserRole
     55                         cmd.ExecuteNonQuery();
     56                     }
     57                 }
     58                 // 提交事务
     59                 trans.Commit();
     60                 lblMsg.Text = String.Format("用户 '{0}' 创建成功。
    事务已提交。", txtUserName.Text);                             
     61             }
     62             catch(Exception inner) {
     63                 // 发生错误,回滚事务
     64                 if (trans != null) trans.Rollback();
     65                 lblMsg.Text = String.Format("用户 '{0}' 创建失败。
    事务已回滚。
    详细信息:{1}", txtUserName.Text, inner.Message);
     66                 //throw new Exception("创建用户失败。事务已回滚。", inner);
     67             }                        
     68         }
     69         // 重新加载 User 数据
     70         grdvUsers.DataBind();
     71     }
     72 
     73     protected void grdvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
     74     {        
     75         // 加载每个 User 对应的 Roles
     76         DataList dlstRolesOfUser = e.Row.FindControl("dlstRolesOfUser") as DataList;
     77         if(dlstRolesOfUser == null) return;
     78         
     79         int userId = (int)grdvUsers.DataKeys[e.Row.RowIndex].Value;
     80         
     81         string sqlSelectRoleOfUser =
     82             "SELECT Role.RoleName FROM (Role INNER JOIN UserRole ON Role.RoleId = UserRole.RoleId) WHERE UserRole.UserId=?";
     83         OleDbDataAdapter da = new OleDbDataAdapter(sqlSelectRoleOfUser, connStr);
     84         da.SelectCommand.Parameters.Add("UserId", userId);
     85         DataTable dtRolesOfUser = new DataTable();
     86         da.Fill(dtRolesOfUser);
     87         dlstRolesOfUser.DataSource = dtRolesOfUser;
     88         dlstRolesOfUser.DataBind();        
     89     }
     90     
     91 </script>
     92 
     93 <html xmlns="http://www.w3.org/1999/xhtml" >
     94 <head runat="server">
     95     <title>多对多写入实例——Access版本</title>
     96 </head>
     97 <body>
     98     <form id="form1" runat="server">
     99     <div>       
    100         <h1>多对多写入实例——Access版本</h1>
    101         <h3>创建用户</h3>
    102         <table border="1">
    103             <tr>
    104                 <td>
    105                     用户名:
    106                 </td>
    107                 <td>
    108                     <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>
    109                     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtUserName"
    110                         Display="Dynamic" ErrorMessage="Required"></asp:RequiredFieldValidator></td>
    111             </tr>
    112             <tr>
    113                 <td>
    114                     密码:
    115                 </td>
    116                 <td>
    117                     <asp:TextBox ID="txtPassword" runat="server"></asp:TextBox></td>
    118             </tr>
    119             <tr>
    120                 <td>
    121                     角色:
    122                 </td>
    123                 <td>
    124                     <asp:CheckBoxList ID="chkRoles" runat="server" DataSourceID="AccessDataSource1" DataTextField="RoleName" DataValueField="RoleId" RepeatDirection="Horizontal"></asp:CheckBoxList><asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="~/App_Data/DemoManyToMany.mdb"
    125                         SelectCommand="SELECT [RoleId], [RoleName] FROM [Role]"></asp:AccessDataSource>
    126                 </td>
    127             </tr>
    128             <tr>
    129                 <td>
    130                     强制发生错误:
    131                 </td>
    132                 <td>
    133                     <asp:CheckBox ID="chkGeneratError" runat="server" /></td>
    134             </tr>
    135             <tr>
    136                 <td>
    137                 </td>
    138                 <td>
    139         <asp:Button ID="btnLogin" runat="server" Text="确定" OnClick="btnLogin_Click" /></td>
    140             </tr>
    141         </table>
    142         <pre><asp:Label ID="lblMsg" runat="server" ForeColor="red"></asp:Label></pre>
    143         <br />
    144     </div>
    145     <h3>用户列表</h3>
    146         <asp:GridView ID="grdvUsers" runat="server" AutoGenerateColumns="False" DataKeyNames="UserId"
    147             DataSourceID="AccessDataSource2" OnRowDataBound="grdvUsers_RowDataBound">
    148             <Columns>
    149                 <asp:BoundField DataField="UserId" HeaderText="UserId" InsertVisible="False" ReadOnly="True"
    150                     SortExpression="UserId" />
    151                 <asp:BoundField DataField="UserName" HeaderText="UserName" SortExpression="UserName" />
    152                 <asp:BoundField DataField="Password" HeaderText="Password" SortExpression="Password" />
    153                 <asp:TemplateField HeaderText="角色">
    154                     <ItemTemplate>
    155                     <asp:Datalist id="dlstRolesOfUser" runat="server" RepeatDirection="Horizontal">
    156                         <ItemTemplate><%# Eval("RoleName") %></ItemTemplate>
    157                         <AlternatingItemTemplate>,<%# Eval("RoleName") %></AlternatingItemTemplate>
    158                     </asp:datalist>
    159                     </ItemTemplate>
    160                 </asp:TemplateField>
    161             </Columns>
    162             <EmptyDataTemplate>
    163                 暂无数据
    164             </EmptyDataTemplate>
    165         </asp:GridView>
    166         <asp:AccessDataSource ID="AccessDataSource2" runat="server" DataFile="~/App_Data/DemoManyToMany.mdb"
    167             SelectCommand="SELECT [UserId], [UserName], [Password] FROM [User]"></asp:AccessDataSource>
    168     </form>
    169 </body>
    170 </html>

    MS SQL Server 版本

      1 <%@ Page Language="C#" %>
      2 <%@ Import Namespace="System.Data" %>
      3 <%@ Import Namespace="System.Data.SqlClient" %>
      4 
      5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      6 
      7 <script runat="server">
      8 
      9     string connStr;
     10 
     11     protected void Page_Load(object sender, EventArgs e)
     12     {
     13         connStr = "server=.;database=DemoLib;uid=sa";
     14     }
     15     
     16     protected void btnLogin_Click(object sender, EventArgs e)
     17     {
     18         if (chkRoles.SelectedIndex == -1) throw new Exception("至少选择一个角色。");        
     19         
     20         string sqlInserUser = "INSERT INTO [User]([UserName], [Password]) VALUES(@UserName, @Password) SELECT @NewUserId=@@Identity";
     21         string sqlInserUserRoel = "INSERT INTO UserRole([UserId], [RoleId]) VALUES(@UserId, @RoleId)";
     22         string sqlSelectNewUserId = "SELECT @@Identity"; // OR "SELECT MAX([UserId]) FROM [User]";
     23         using (SqlConnection conn = new SqlConnection(connStr)) {            
     24             conn.Open();
     25             // 显示开启事务
     26             SqlTransaction trans = conn.BeginTransaction();            
     27             SqlCommand cmd = conn.CreateCommand();
     28             // 关联事务
     29             cmd.Transaction = trans;           
     30             
     31             try {
     32                 cmd.CommandText = sqlInserUser;
     33                 cmd.Parameters.Add("UserName", txtUserName.Text);
     34                 cmd.Parameters.Add("Password", txtPassword.Text);
     35                 // 此输出参数返回新插入 UserId
     36                 cmd.Parameters.Add("NewUserId", SqlDbType.Int).Direction = ParameterDirection.Output;
     37                 // 插入 User
     38                 cmd.ExecuteNonQuery();                               
     39 
     40                 /**//* 以下方法依然有效,只是我们选择更加简便方法:批处理SQL语句
     41                 cmd.CommandText = sqlSelectNewUserId;
     42                 // 读取新插入 UserId
     43                 int newUserId = (int)cmd.ExecuteScalar();
     44                  */
     45                 int newUserId = (int)cmd.Parameters["NewUserId"].Value;
     46 
     47                 // 仅供测试
     48                 if (chkGeneratError.Checked) throw new Exception("创建用户时发生错误。");
     49 
     50                 cmd.CommandText = sqlInserUserRoel;
     51                 cmd.Parameters.Clear();
     52                 cmd.Parameters.Add("UserId", SqlDbType.Int);
     53                 cmd.Parameters.Add("RoleId", SqlDbType.Int);
     54                 cmd.Parameters[0].Value = newUserId;
     55                 // 遍历可选角色列表
     56                 foreach (ListItem item in chkRoles.Items) {
     57                     if (item.Selected) {
     58                         cmd.Parameters[1].Value = item.Value;
     59                         // 写入中间关系表 UserRole
     60                         cmd.ExecuteNonQuery();
     61                     }
     62                 }
     63                 // 提交事务
     64                 trans.Commit();
     65                 lblMsg.Text = String.Format("用户 '{0}' 创建成功。
    事务已提交。", txtUserName.Text);                             
     66             }
     67             catch(Exception inner) {
     68                 // 发生错误,回滚事务
     69                 if (trans != null) trans.Rollback();
     70                 lblMsg.Text = String.Format("用户 '{0}' 创建失败。
    事务已回滚。
    详细信息:{1}", txtUserName.Text, inner.Message);
     71                 //throw new Exception("创建用户失败。事务已回滚。", inner);
     72             }                        
     73         }
     74         // 重新加载 User 数据
     75         grdvUsers.DataBind();
     76     }
     77 
     78     protected void grdvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
     79     {        
     80         // 加载每个 User 对应的 Roles
     81         DataList dlstRolesOfUser = e.Row.FindControl("dlstRolesOfUser") as DataList;
     82         if(dlstRolesOfUser == null) return;
     83         
     84         int userId = (int)grdvUsers.DataKeys[e.Row.RowIndex].Value;
     85         
     86         string sqlSelectRoleOfUser =
     87             "SELECT Role.RoleName FROM (Role INNER JOIN UserRole ON Role.RoleId = UserRole.RoleId) WHERE UserRole.UserId=@UserId";
     88         SqlDataAdapter da = new SqlDataAdapter(sqlSelectRoleOfUser, connStr);
     89         da.SelectCommand.Parameters.Add("UserId", userId);
     90         DataTable dtRolesOfUser = new DataTable();
     91         da.Fill(dtRolesOfUser);
     92         dlstRolesOfUser.DataSource = dtRolesOfUser;
     93         dlstRolesOfUser.DataBind();        
     94     }
     95     
     96 </script>
     97 
     98 <html xmlns="http://www.w3.org/1999/xhtml" >
     99 <head runat="server">
    100     <title>多对多写入实例——SqlServer版本</title>
    101 </head>
    102 <body>
    103     <form id="form1" runat="server">
    104     <div>       
    105         <h1>多对多写入实例——SqlServer版本</h1>
    106         <h3>创建用户</h3>
    107         <table border="1">
    108             <tr>
    109                 <td>
    110                     用户名:
    111                 </td>
    112                 <td>
    113                     <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>
    114                     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtUserName"
    115                         Display="Dynamic" ErrorMessage="Required"></asp:RequiredFieldValidator></td>
    116             </tr>
    117             <tr>
    118                 <td>
    119                     密码:
    120                 </td>
    121                 <td>
    122                     <asp:TextBox ID="txtPassword" runat="server"></asp:TextBox></td>
    123             </tr>
    124             <tr>
    125                 <td>
    126                     角色:
    127                 </td>
    128                 <td>
    129                     <asp:CheckBoxList ID="chkRoles" runat="server" DataSourceID="SqlDataSource1" DataTextField="RoleName" DataValueField="RoleId" RepeatDirection="Horizontal"></asp:CheckBoxList><asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="Data Source=.;Initial Catalog=DemoLib;Integrated Security=True"
    130                         ProviderName="System.Data.SqlClient" SelectCommand="SELECT [RoleId], [RoleName] FROM [Role]">
    131                     </asp:SqlDataSource>
    132                 </td>
    133             </tr>
    134             <tr>
    135                 <td>
    136                     强制发生错误:
    137                 </td>
    138                 <td>
    139                     <asp:CheckBox ID="chkGeneratError" runat="server" /></td>
    140             </tr>
    141             <tr>
    142                 <td>
    143                 </td>
    144                 <td>
    145         <asp:Button ID="btnLogin" runat="server" Text="确定" OnClick="btnLogin_Click" /></td>
    146             </tr>
    147         </table>
    148         <pre><asp:Label ID="lblMsg" runat="server" ForeColor="red"></asp:Label></pre>
    149         <br />
    150     </div>
    151     <h3>用户列表</h3>
    152         <asp:GridView ID="grdvUsers" runat="server" AutoGenerateColumns="False" DataKeyNames="UserId"
    153             DataSourceID="SqlDataSource2" OnRowDataBound="grdvUsers_RowDataBound">
    154             <Columns>
    155                 <asp:BoundField DataField="UserId" HeaderText="UserId" InsertVisible="False" ReadOnly="True"
    156                     SortExpression="UserId" />
    157                 <asp:BoundField DataField="UserName" HeaderText="UserName" SortExpression="UserName" />
    158                 <asp:BoundField DataField="Password" HeaderText="Password" SortExpression="Password" />
    159                 <asp:TemplateField HeaderText="角色">
    160                     <ItemTemplate>
    161                     <asp:Datalist id="dlstRolesOfUser" runat="server" RepeatDirection="Horizontal">
    162                         <ItemTemplate><%# Eval("RoleName") %></ItemTemplate>
    163                         <AlternatingItemTemplate>,<%# Eval("RoleName") %></AlternatingItemTemplate>
    164                     </asp:datalist>
    165                     </ItemTemplate>
    166                 </asp:TemplateField>
    167             </Columns>
    168             <EmptyDataTemplate>
    169                 暂无数据
    170             </EmptyDataTemplate>
    171         </asp:GridView>
    172         <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="Data Source=.;Initial Catalog=DemoLib;Integrated Security=True"
    173             ProviderName="System.Data.SqlClient" SelectCommand="SELECT [UserId], [UserName], [Password] FROM [User]">
    174         </asp:SqlDataSource>
    175         &nbsp;
    176     </form>
    177 </body>
    178 </html>
  • 相关阅读:
    informix数据库的日志
    javaScript之BOM操作2
    javaScript之BOM操作1
    开发必会系列:hibernate事务
    性能测试系列:Oracle数据库awr报告使用与分析
    《股票大作手回忆录》读书笔记
    金融知识学习综合笔记
    开发必会系列:《深入理解JVM(第二版)》读书笔记
    基础教材系列:计算机底层知识点积累
    基础教材系列:数据结构与算法——慕课网笔记
  • 原文地址:https://www.cnblogs.com/lusunqing/p/3326281.html
Copyright © 2020-2023  润新知