如何获取自增长列(标识列)的ID,并写入另一张表(多对多关系插入数据示例)...

问题
CSDN 里面不时有初学者疑惑:如何获取自增长列(标识列)的ID,并写入另一张表。

场景
这里选择典型的多对多关系,并以常见的 User-Role 作为 Demo,同时显示 Access 和 Sql Server 版本

关系图


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

MS Access 版本 

ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#"  %>
ExpandedBlockStart.gifContractedBlock.gif
<% dot.gif @ Import Namespace="System.Data"  %>
ExpandedBlockStart.gifContractedBlock.gif
<% dot.gif @ Import Namespace="System.Data.OleDb"  %>
None.gif
None.gif
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
None.gif
ExpandedBlockStart.gifContractedBlock.gif
< script  runat ="server" > dot.gif
InBlock.gif
InBlock.gif    string connStr;
InBlock.gif
InBlock.gif    protected 
void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        connStr 
= "provider=Microsoft.Jet.OleDb.4.0;data source=" + Server.MapPath("~/App_Data/DemoManyToMany.mdb");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    protected 
void btnLogin_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (chkRoles.SelectedIndex == -1throw new Exception("至少选择一个角色。");        
InBlock.gif        
InBlock.gif        string sqlInserUser 
= "INSERT INTO [User]([UserName], [Password]) VALUES(?, ?)";
InBlock.gif        string sqlInserUserRoel 
= "INSERT INTO UserRole([UserId], [RoleId]) VALUES(?, ?)";
InBlock.gif        string sqlSelectNewUserId 
= "SELECT @@Identity"// OR "SELECT MAX([UserId]) FROM [User]";
ExpandedSubBlockStart.gifContractedSubBlock.gif
        using (OleDbConnection conn = new OleDbConnection(connStr)) dot.gif{            
InBlock.gif            conn.Open();
InBlock.gif            
// 显示开启事务
InBlock.gif
            OleDbTransaction trans = conn.BeginTransaction();            
InBlock.gif            OleDbCommand cmd 
= conn.CreateCommand();
InBlock.gif            
// 关联事务
InBlock.gif
            cmd.Transaction = trans;           
InBlock.gif            
ExpandedSubBlockStart.gifContractedSubBlock.gif            
try dot.gif{
InBlock.gif                cmd.CommandText 
= sqlInserUser;
InBlock.gif                cmd.Parameters.Add(
"UserName", txtUserName.Text);
InBlock.gif                cmd.Parameters.Add(
"Password", txtPassword.Text);
InBlock.gif                
// 插入 User
InBlock.gif
                cmd.ExecuteNonQuery();                               
InBlock.gif
InBlock.gif                cmd.CommandText 
= sqlSelectNewUserId;
InBlock.gif                
// 读取新插入 UserId
InBlock.gif
                int newUserId = (int)cmd.ExecuteScalar();
InBlock.gif
InBlock.gif                
// 仅供测试
InBlock.gif
                if (chkGeneratError.Checked) throw new Exception("创建用户时发生错误。");
InBlock.gif
InBlock.gif                cmd.CommandText 
= sqlInserUserRoel;
InBlock.gif                cmd.Parameters.Clear();
InBlock.gif                cmd.Parameters.Add(
"UserId", OleDbType.Integer);
InBlock.gif                cmd.Parameters.Add(
"RoleId", OleDbType.Integer);
InBlock.gif                cmd.Parameters[
0].Value = newUserId;
InBlock.gif                
// 遍历可选角色列表
ExpandedSubBlockStart.gifContractedSubBlock.gif
                foreach (ListItem item in chkRoles.Items) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
if (item.Selected) dot.gif{
InBlock.gif                        cmd.Parameters[
1].Value = item.Value;
InBlock.gif                        
// 写入中间关系表 UserRole
InBlock.gif
                        cmd.ExecuteNonQuery();
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
// 提交事务
InBlock.gif
                trans.Commit();
InBlock.gif                lblMsg.Text 
= String.Format("用户 '{0}' 创建成功。\n事务已提交。", txtUserName.Text);                             
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
catch(Exception inner) dot.gif{
InBlock.gif                
// 发生错误,回滚事务
InBlock.gif
                if (trans != null) trans.Rollback();
InBlock.gif                lblMsg.Text 
= String.Format("用户 '{0}' 创建失败。\n事务已回滚。\n详细信息:{1}", txtUserName.Text, inner.Message);
InBlock.gif                
//throw new Exception("创建用户失败。事务已回滚。", inner);
ExpandedSubBlockEnd.gif
            }
                        
ExpandedSubBlockEnd.gif        }

InBlock.gif        
// 重新加载 User 数据
InBlock.gif
        grdvUsers.DataBind();
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    protected 
void grdvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{        
InBlock.gif        
// 加载每个 User 对应的 Roles
InBlock.gif
        DataList dlstRolesOfUser = e.Row.FindControl("dlstRolesOfUser") as DataList;
InBlock.gif        
if(dlstRolesOfUser == nullreturn;
InBlock.gif        
InBlock.gif        
int userId = (int)grdvUsers.DataKeys[e.Row.RowIndex].Value;
InBlock.gif        
InBlock.gif        string sqlSelectRoleOfUser 
=
InBlock.gif            
"SELECT Role.RoleName FROM (Role INNER JOIN UserRole ON Role.RoleId = UserRole.RoleId) WHERE UserRole.UserId=?";
InBlock.gif        OleDbDataAdapter da 
= new OleDbDataAdapter(sqlSelectRoleOfUser, connStr);
InBlock.gif        da.SelectCommand.Parameters.Add(
"UserId", userId);
InBlock.gif        DataTable dtRolesOfUser 
= new DataTable();
InBlock.gif        da.Fill(dtRolesOfUser);
InBlock.gif        dlstRolesOfUser.DataSource 
= dtRolesOfUser;
InBlock.gif        dlstRolesOfUser.DataBind();        
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif    
None.gif
</ script >
None.gif
None.gif
< html  xmlns ="http://www.w3.org/1999/xhtml"   >
None.gif
< head  runat ="server" >
None.gif    
< title > 多对多写入实例——Access版本 </ title >
None.gif
</ head >
None.gif
< body >
None.gif    
< form  id ="form1"  runat ="server" >
None.gif    
< div >        
None.gif        
< h1 > 多对多写入实例——Access版本 </ h1 >
None.gif        
< h3 > 创建用户 </ h3 >
None.gif        
< table  border ="1" >
None.gif            
< tr >
None.gif                
< td >
None.gif                    用户名:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< asp:TextBox  ID ="txtUserName"  runat ="server" ></ asp:TextBox >
None.gif                    
< asp:RequiredFieldValidator  ID ="RequiredFieldValidator1"  runat ="server"  ControlToValidate ="txtUserName"
None.gif                        Display
="Dynamic"  ErrorMessage ="Required" ></ asp:RequiredFieldValidator ></ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                    密码:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< asp:TextBox  ID ="txtPassword"  runat ="server" ></ asp:TextBox ></ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                    角色:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< 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"
None.gif                        SelectCommand
="SELECT [RoleId], [RoleName] FROM [Role]" ></ asp:AccessDataSource >
None.gif                
</ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                    强制发生错误:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< asp:CheckBox  ID ="chkGeneratError"  runat ="server"   /></ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                
</ td >
None.gif                
< td >
None.gif        
< asp:Button  ID ="btnLogin"  runat ="server"  Text ="确定"  OnClick ="btnLogin_Click"   /></ td >
None.gif            
</ tr >
None.gif        
</ table >
None.gif        
< pre >< asp:Label  ID ="lblMsg"  runat ="server"  ForeColor ="red" ></ asp:Label ></ pre >
None.gif        
< br  />
None.gif    
</ div >
None.gif    
< h3 > 用户列表 </ h3 >
None.gif        
< asp:GridView  ID ="grdvUsers"  runat ="server"  AutoGenerateColumns ="False"  DataKeyNames ="UserId"
None.gif            DataSourceID
="AccessDataSource2"  OnRowDataBound ="grdvUsers_RowDataBound" >
None.gif            
< Columns >
None.gif                
< asp:BoundField  DataField ="UserId"  HeaderText ="UserId"  InsertVisible ="False"  ReadOnly ="True"
None.gif                    SortExpression
="UserId"   />
None.gif                
< asp:BoundField  DataField ="UserName"  HeaderText ="UserName"  SortExpression ="UserName"   />
None.gif                
< asp:BoundField  DataField ="Password"  HeaderText ="Password"  SortExpression ="Password"   />
None.gif                
< asp:TemplateField  HeaderText ="角色" >
None.gif                    
< ItemTemplate >
None.gif                    
< asp:Datalist  id ="dlstRolesOfUser"  runat ="server"  RepeatDirection ="Horizontal" >
ExpandedBlockStart.gifContractedBlock.gif                        
< ItemTemplate > <% dot.gif Eval("RoleName" %> </ ItemTemplate >
ExpandedBlockStart.gifContractedBlock.gif                        
< AlternatingItemTemplate > , <% dot.gif Eval("RoleName" %> </ AlternatingItemTemplate >
None.gif                    
</ asp:datalist >
None.gif                    
</ ItemTemplate >
None.gif                
</ asp:TemplateField >
None.gif            
</ Columns >
None.gif            
< EmptyDataTemplate >
None.gif                暂无数据
None.gif            
</ EmptyDataTemplate >
None.gif        
</ asp:GridView >
None.gif        
< asp:AccessDataSource  ID ="AccessDataSource2"  runat ="server"  DataFile ="~/App_Data/DemoManyToMany.mdb"
None.gif            SelectCommand
="SELECT [UserId], [UserName], [Password] FROM [User]" ></ asp:AccessDataSource >
None.gif    
</ form >
None.gif
</ body >
None.gif
</ html >
None.gif

MS SQL Server 版本

ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#"  %>
ExpandedBlockStart.gifContractedBlock.gif
<% dot.gif @ Import Namespace="System.Data"  %>
ExpandedBlockStart.gifContractedBlock.gif
<% dot.gif @ Import Namespace="System.Data.SqlClient"  %>
None.gif
None.gif
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
None.gif
ExpandedBlockStart.gifContractedBlock.gif
< script  runat ="server" > dot.gif
InBlock.gif
InBlock.gif    string connStr;
InBlock.gif
InBlock.gif    protected 
void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        connStr 
= "server=.;database=DemoLib;uid=sa";
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    protected 
void btnLogin_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (chkRoles.SelectedIndex == -1throw new Exception("至少选择一个角色。");        
InBlock.gif        
InBlock.gif        string sqlInserUser 
= "INSERT INTO [User]([UserName], [Password]) VALUES(@UserName, @Password) SELECT @NewUserId=@@Identity";
InBlock.gif        string sqlInserUserRoel 
= "INSERT INTO UserRole([UserId], [RoleId]) VALUES(@UserId, @RoleId)";
InBlock.gif        string sqlSelectNewUserId 
= "SELECT @@Identity"// OR "SELECT MAX([UserId]) FROM [User]";
ExpandedSubBlockStart.gifContractedSubBlock.gif
        using (SqlConnection conn = new SqlConnection(connStr)) dot.gif{            
InBlock.gif            conn.Open();
InBlock.gif            
// 显示开启事务
InBlock.gif
            SqlTransaction trans = conn.BeginTransaction();            
InBlock.gif            SqlCommand cmd 
= conn.CreateCommand();
InBlock.gif            
// 关联事务
InBlock.gif
            cmd.Transaction = trans;           
InBlock.gif            
ExpandedSubBlockStart.gifContractedSubBlock.gif            
try dot.gif{
InBlock.gif                cmd.CommandText 
= sqlInserUser;
InBlock.gif                cmd.Parameters.Add(
"UserName", txtUserName.Text);
InBlock.gif                cmd.Parameters.Add(
"Password", txtPassword.Text);
InBlock.gif                
// 此输出参数返回新插入 UserId
InBlock.gif
                cmd.Parameters.Add("NewUserId", SqlDbType.Int).Direction = ParameterDirection.Output;
InBlock.gif                
// 插入 User
InBlock.gif
                cmd.ExecuteNonQuery();                               
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//* 以下方法依然有效,只是我们选择更加简便方法:批处理SQL语句
InBlock.gif                cmd.CommandText = sqlSelectNewUserId;
InBlock.gif                // 读取新插入 UserId
InBlock.gif                int newUserId = (int)cmd.ExecuteScalar();
ExpandedSubBlockEnd.gif                 
*/

InBlock.gif                
int newUserId = (int)cmd.Parameters["NewUserId"].Value;
InBlock.gif
InBlock.gif                
// 仅供测试
InBlock.gif
                if (chkGeneratError.Checked) throw new Exception("创建用户时发生错误。");
InBlock.gif
InBlock.gif                cmd.CommandText 
= sqlInserUserRoel;
InBlock.gif                cmd.Parameters.Clear();
InBlock.gif                cmd.Parameters.Add(
"UserId", SqlDbType.Int);
InBlock.gif                cmd.Parameters.Add(
"RoleId", SqlDbType.Int);
InBlock.gif                cmd.Parameters[
0].Value = newUserId;
InBlock.gif                
// 遍历可选角色列表
ExpandedSubBlockStart.gifContractedSubBlock.gif
                foreach (ListItem item in chkRoles.Items) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
if (item.Selected) dot.gif{
InBlock.gif                        cmd.Parameters[
1].Value = item.Value;
InBlock.gif                        
// 写入中间关系表 UserRole
InBlock.gif
                        cmd.ExecuteNonQuery();
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
// 提交事务
InBlock.gif
                trans.Commit();
InBlock.gif                lblMsg.Text 
= String.Format("用户 '{0}' 创建成功。\n事务已提交。", txtUserName.Text);                             
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
catch(Exception inner) dot.gif{
InBlock.gif                
// 发生错误,回滚事务
InBlock.gif
                if (trans != null) trans.Rollback();
InBlock.gif                lblMsg.Text 
= String.Format("用户 '{0}' 创建失败。\n事务已回滚。\n详细信息:{1}", txtUserName.Text, inner.Message);
InBlock.gif                
//throw new Exception("创建用户失败。事务已回滚。", inner);
ExpandedSubBlockEnd.gif
            }
                        
ExpandedSubBlockEnd.gif        }

InBlock.gif        
// 重新加载 User 数据
InBlock.gif
        grdvUsers.DataBind();
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    protected 
void grdvUsers_RowDataBound(object sender, GridViewRowEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{        
InBlock.gif        
// 加载每个 User 对应的 Roles
InBlock.gif
        DataList dlstRolesOfUser = e.Row.FindControl("dlstRolesOfUser") as DataList;
InBlock.gif        
if(dlstRolesOfUser == nullreturn;
InBlock.gif        
InBlock.gif        
int userId = (int)grdvUsers.DataKeys[e.Row.RowIndex].Value;
InBlock.gif        
InBlock.gif        string sqlSelectRoleOfUser 
=
InBlock.gif            
"SELECT Role.RoleName FROM (Role INNER JOIN UserRole ON Role.RoleId = UserRole.RoleId) WHERE UserRole.UserId=@UserId";
InBlock.gif        SqlDataAdapter da 
= new SqlDataAdapter(sqlSelectRoleOfUser, connStr);
InBlock.gif        da.SelectCommand.Parameters.Add(
"UserId", userId);
InBlock.gif        DataTable dtRolesOfUser 
= new DataTable();
InBlock.gif        da.Fill(dtRolesOfUser);
InBlock.gif        dlstRolesOfUser.DataSource 
= dtRolesOfUser;
InBlock.gif        dlstRolesOfUser.DataBind();        
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif    
None.gif
</ script >
None.gif
None.gif
< html  xmlns ="http://www.w3.org/1999/xhtml"   >
None.gif
< head  runat ="server" >
None.gif    
< title > 多对多写入实例——SqlServer版本 </ title >
None.gif
</ head >
None.gif
< body >
None.gif    
< form  id ="form1"  runat ="server" >
None.gif    
< div >        
None.gif        
< h1 > 多对多写入实例——SqlServer版本 </ h1 >
None.gif        
< h3 > 创建用户 </ h3 >
None.gif        
< table  border ="1" >
None.gif            
< tr >
None.gif                
< td >
None.gif                    用户名:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< asp:TextBox  ID ="txtUserName"  runat ="server" ></ asp:TextBox >
None.gif                    
< asp:RequiredFieldValidator  ID ="RequiredFieldValidator1"  runat ="server"  ControlToValidate ="txtUserName"
None.gif                        Display
="Dynamic"  ErrorMessage ="Required" ></ asp:RequiredFieldValidator ></ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                    密码:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< asp:TextBox  ID ="txtPassword"  runat ="server" ></ asp:TextBox ></ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                    角色:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< 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"
None.gif                        ProviderName
="System.Data.SqlClient"  SelectCommand ="SELECT [RoleId], [RoleName] FROM [Role]" >
None.gif                    
</ asp:SqlDataSource >
None.gif                
</ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                    强制发生错误:
None.gif                
</ td >
None.gif                
< td >
None.gif                    
< asp:CheckBox  ID ="chkGeneratError"  runat ="server"   /></ td >
None.gif            
</ tr >
None.gif            
< tr >
None.gif                
< td >
None.gif                
</ td >
None.gif                
< td >
None.gif        
< asp:Button  ID ="btnLogin"  runat ="server"  Text ="确定"  OnClick ="btnLogin_Click"   /></ td >
None.gif            
</ tr >
None.gif        
</ table >
None.gif        
< pre >< asp:Label  ID ="lblMsg"  runat ="server"  ForeColor ="red" ></ asp:Label ></ pre >
None.gif        
< br  />
None.gif    
</ div >
None.gif    
< h3 > 用户列表 </ h3 >
None.gif        
< asp:GridView  ID ="grdvUsers"  runat ="server"  AutoGenerateColumns ="False"  DataKeyNames ="UserId"
None.gif            DataSourceID
="SqlDataSource2"  OnRowDataBound ="grdvUsers_RowDataBound" >
None.gif            
< Columns >
None.gif                
< asp:BoundField  DataField ="UserId"  HeaderText ="UserId"  InsertVisible ="False"  ReadOnly ="True"
None.gif                    SortExpression
="UserId"   />
None.gif                
< asp:BoundField  DataField ="UserName"  HeaderText ="UserName"  SortExpression ="UserName"   />
None.gif                
< asp:BoundField  DataField ="Password"  HeaderText ="Password"  SortExpression ="Password"   />
None.gif                
< asp:TemplateField  HeaderText ="角色" >
None.gif                    
< ItemTemplate >
None.gif                    
< asp:Datalist  id ="dlstRolesOfUser"  runat ="server"  RepeatDirection ="Horizontal" >
ExpandedBlockStart.gifContractedBlock.gif                        
< ItemTemplate > <% dot.gif Eval("RoleName" %> </ ItemTemplate >
ExpandedBlockStart.gifContractedBlock.gif                        
< AlternatingItemTemplate > , <% dot.gif Eval("RoleName" %> </ AlternatingItemTemplate >
None.gif                    
</ asp:datalist >
None.gif                    
</ ItemTemplate >
None.gif                
</ asp:TemplateField >
None.gif            
</ Columns >
None.gif            
< EmptyDataTemplate >
None.gif                暂无数据
None.gif            
</ EmptyDataTemplate >
None.gif        
</ asp:GridView >
None.gif        
< asp:SqlDataSource  ID ="SqlDataSource2"  runat ="server"  ConnectionString ="Data Source=.;Initial Catalog=DemoLib;Integrated Security=True"
None.gif            ProviderName
="System.Data.SqlClient"  SelectCommand ="SELECT [UserId], [UserName], [Password] FROM [User]" >
None.gif        
</ asp:SqlDataSource >
None.gif        
&nbsp;
None.gif    
</ form >
None.gif
</ body >
None.gif
</ html >
None.gif

下载: /Files/Jinglecat/DemoManyToMany_Insert.rar

update 2007年7月30日
这里 zjp1978 (铁血柔情) 提到 Access 中使用 @@Identity 无法获取正确值,主要原因是,没有使用显示事务,详细讨论见: http://community.csdn.net/Expert/TopicView3.asp?id=5661149 

转载于:https://www.cnblogs.com/Jinglecat/archive/2007/07/05/806421.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值