转:获得数据库⾃增长ID(ACCESS)与(SQLSERVER)
问题
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""/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
7 <script runat="server">
8
9string connStr;
10
11protected 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
16protected void btnLogin_Click(object sender, EventArgs e)
17    {
18if (chkRoles.SelectedIndex == -1) throw new Exception("⾄少选择⼀个⾓⾊。");
19
20string sqlInserUser = "INSERT INTO [User]([UserName], [Password]) VALUES(?, ?)";
21string sqlInserUserRoel = "INSERT INTO UserRole([UserId], [RoleId]) VALUES(?, ?)";
22string sqlSelectNewUserId = "SELECT @@Identity"; // OR "SELECT MAX([UserId]) FROM [User]";
23using (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
31try {
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
40int newUserId = (int)cmd.ExecuteScalar();
41
42// 仅供测试
43if (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// 遍历可选⾓⾊列表
51foreach (ListItem item in chkRoles.Items) {
52if (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}' 创建成功。\n事务已提交。", txtUserName.Text);
61            }
62catch(Exception inner) {
63// 发⽣错误,回滚事务
64if (trans != null) trans.Rollback();
65                lblMsg.Text = String.Format("⽤户 '{0}' 创建失败。\n事务已回滚。\n详细信息:{1}", txtUserName.Text, inner.Message);
66//throw new Exception("创建⽤户失败。事务已回滚。", inner);
67            }
68        }
69// 重新加载 User 数据
70        grdvUsers.DataBind();
71    }
72
73protected void grdvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
74    {
75// 加载每个 User 对应的 Roles
76        DataList dlstRolesOfUser = e.Row.FindControl("dlstRolesOfUser") as DataList;
77if(dlstRolesOfUser == null) return;
78
79int userId = (int)grdvUsers.DataKeys[e.Row.RowIndex].Value;
80
81string 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="/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= 125                        SelectCommand="SELECT [RoleId], [RoleName] FROM [Role]"></asp:AccessDataSource>sqltransaction什么意思
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="U
serName" />
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""/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
7 <script runat="server">
8
9string connStr;
10
11protected void Page_Load(object sender, EventArgs e)
12    {
13        connStr = "server=.;database=DemoLib;uid=sa";
14    }
15
16protected void btnLogin_Click(object sender, EventArgs e)
17    {
18if (chkRoles.SelectedIndex == -1) throw new Exception("⾄少选择⼀个⾓⾊。");
19
20string sqlInserUser = "INSERT INTO [User]([UserName], [Password]) VALUES(@UserName, @Password) SELECT @NewUserId=@@Identity"; 21string sqlInserUserRoel = "INSERT INTO UserRole([UserId], [RoleId]) VALUES(@UserId, @RoleId)";
22string sqlSelectNewUserId = "SELECT @@Identity"; // OR "SELECT MAX([UserId]) FROM [User]";
23using (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
31try {
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*/
45int newUserId = (int)cmd.Parameters["NewUserId"].Value;
46
47// 仅供测试
48if (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// 遍历可选⾓⾊列表
56foreach (ListItem item in chkRoles.Items) {
57if (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}' 创建成功。\n事务已提交。", txtUserName.Text);
66            }
67catch(Exception inner) {
68// 发⽣错误,回滚事务
69if (trans != null) trans.Rollback();
70                lblMsg.Text = String.Format("⽤户 '{0}' 创建失败。\n事务已回滚。\n详细信息:{1}", txtUserName.Text, inner.Message);
71//throw new Exception("创建⽤户失败。事务已回滚。", inner);
72            }
73        }
74// 重新加载 User 数据
75        grdvUsers.DataBind();
76    }
77
78protected void grdvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
79    {
80// 加载每个 User 对应的 Roles
81        DataList dlstRolesOfUser = e.Row.FindControl("dlstRolesOfUser") as DataList;
82if(dlstRolesOfUser == null) return;
83
84int userId = (int)grdvUsers.DataKeys[e.Row.RowIndex].Value;
85
86string 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="/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= 130                        ProviderName="System.Data.SqlC
lient" 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         
176    </form>
177 </body>
178 </html>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。