传参

本文介绍参数化SQL语句的使用方法及其在不同数据库中的实现方式,包括SQL Server、Access、MySQL和Oracle等,强调了其在防止SQL注入攻击和提高性能方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一是所有的SQL语句都存放在存储过程中,这样不但可以避免SQL注入,还能提高一些性能,并且存储过程可以由专门的数据库管理员(DBA)编写和集中管理,不过这种做法有时候针对相同的几个表有不同条件的查询,SQL语句可能不同,这样就会编写大量的存储过程,所以有人提出了第二种方案:参数化SQL语句。例如我们在本篇中创建的表UserInfo中查找所有女性用户,那么通常情况下我们的SQL语句可能是这样:

1select * from UserInfo where sex=0

在参数化SQL语句中我们将数值以参数化的形式提供,对于上面的查询,我们用参数化SQL语句表示为: 

1select * from UserInfo where sex=@sex

再对代码中对这个SQL语句中的参数进行赋值,假如我们要查找UserInfo表中所有年龄大于30岁的男性用户,这个参数化SQL语句可以这么写:

1select * from UserInfo where sex=@sex and age>@age

下面是执行这个查询并且将查询结果集以DataTable的方式返回的代码: 

01//实例化Connection对象 
02SqlConnection connection = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=''"); 
03//实例化Command对象 
04SqlCommand command = new SqlCommand("select * from UserInfo where sex=@sex and age>@age", connection); 
05//第一种添加查询参数的例子 
06command.Parameters.AddWithValue("@sex", true); 
07//第二种添加查询参数的例子 
08SqlParameter parameter = new SqlParameter("@age", SqlDbType.Int);//注意UserInfo表里age字段是int类型的 
09parameter.Value = 30; 
10command.Parameters.Add(parameter);//添加参数 
11//实例化DataAdapter 
12SqlDataAdapter adapter = new SqlDataAdapter(command); 
13DataTable data = new DataTable();

 

 

上面的代码是访问SQL Server数据库的代码。如果本文中提到的数据分别在Access、MySQL、Oracle数据库,那么对应的参数化SQL语句及参数分别如下:

 

 

 

数据库AccessMySQLOracle
 SQL语句select * from UserInfo
where sex=? and age>?
select * from UserInfo
where sex=?sex and age>?age
select * from UserInfo
where sex=:sex and age>:age
参数OleDbParameterMySqlParameterOracleParameter
实例化参数OleDbParameter p=new OleDbParameter(“?”, OleDbType. Boolean);MySqlParameter p=new MySqlParameter(“?sex”, MySqlDbType.Bit);OracleParameter p=new OracleParameter(“:sex”, OracleType.Byte);
赋值p.Value=true;p.Value=1;p.Value=1;

 

通过上面的实例代码我们可以看出尽管SQL语句大体相似,但是在不同数据库的特点,可能参数化SQL语句不同,例如在Access中参数化SQL语句是在参数直接以“?”作为参数名,在SQL Server中是参数有“@”前缀,在MySQL中是参数有“?”前缀,在Oracle中参数以“:”为前缀。
注意:因为在Access中参数名都是“?”,所以给参数赋值一定要按照列顺序赋值,否则就有可能执行出错。

 

 

 

 

        public int AddTypeParms(PhotoType type)
        {
            StringBuilder strsql = new StringBuilder();
            strsql.Append("insert into PhotoType (");
            strsql.Append("TypeNameCN,TypeNameEN,SortID,DefaultImg)");
            strsql.Append(" values (");
            strsql.Append("@TypeNameCN,@TypeNameEN,@SortID,@DefaultImg)");
            OleDbParameter[] parameters ={
                      new OleDbParameter("@TypeNameCN",OleDbType.VarWChar),
                      new OleDbParameter("@TypeNameEN",OleDbType.VarWChar),
                      new OleDbParameter("@SortID",OleDbType.SmallInt),
                      new OleDbParameter("@DefaultImg",OleDbType.VarWChar)
                                       
                                        };
            parameters[0].Value = type.TypeNameCN;
            parameters[1].Value = type.TypeNameEN;
            parameters[2].Value = type.SortID;
            parameters[3].Value = type.Img;

            object obj=DBHelper.GetSingle(strsql.ToString(),parameters);
            if(obj==null)
            {
                return 1;
            }
            else
            {
                return Convert.ToInt32(obj);
            }
       
        }

 

 

 

       private static void PrepareCommand(OleDbCommand cmd, OleDbConnection conn, OleDbTransaction trans, string cmdText, OleDbParameter[] cmdParms)
       {
           if (conn.State != ConnectionState.Open)
               conn.Open();
           cmd.Connection = conn;
           cmd.CommandText = cmdText;
           if (trans != null)
               cmd.Transaction = trans;
           cmd.CommandType = CommandType.Text;//cmdType;
           if (cmdParms != null)
           {


               foreach (OleDbParameter parameter in cmdParms)
               {
                   if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
                       (parameter.Value == null))
                   {
                       parameter.Value = DBNull.Value;
                   }
                   cmd.Parameters.Add(parameter);
               }
           }
       }
       public static int ExecuteSql(string SQLString, params  OleDbParameter[] cmdParms)
       {
           using (OleDbConnection connection = new OleDbConnection(constr))
           {
               using (OleDbCommand cmd = new OleDbCommand())
               {
                   PrepareCommand(cmd, connection, null, SQLString, cmdParms);
                   int rows = cmd.ExecuteNonQuery();
                   cmd.Parameters.Clear();
                   return rows;
               }
           }
       }
               /// <summary>
        /// 执行一条计算查询结果语句,返回查询结果(object)。
        /// </summary>
        /// <param name="SQLString">计算查询结果语句</param>
        /// <returns>查询结果(object)</returns>
       public static object GetSingle(string SQLString, params OleDbParameter[] cmdParms)
       {
           using (OleDbConnection connection = new OleDbConnection(constr))
           {
               using (OleDbCommand cmd = new OleDbCommand())
               {
                   try
                   {
                       PrepareCommand(cmd, connection, null, SQLString, cmdParms);
                       object obj = cmd.ExecuteScalar();
                       cmd.Parameters.Clear();
                       if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
                       {
                           return null;
                       }
                       else
                       {
                           return obj;
                       }
                   }
                   catch (System.Data.OleDb.OleDbException e)
                   {
                       throw e;
                   }
               }
           }
       }

 

 

 

   声明参数:OleDbParameter para = new OleDbParameter("@string", DbType.String, 50);其中DbType.String应该改成:OleDbType.VarWChar。DbType,OleDbType,SqlDbType对应如下:


访问类型名称 数据库数据类型 OLEDB 类型 .NET 框架类型 成员名称
文本 VarWChar DBTYPE _ WSTR System.String OleDbType.VarWChar
备忘录 LongVarWCha R DBTYPE _ WSTR System.String OleDbType.LongVarWChar
字节数: UnsignedTinyInt DBTYPE _ UI 1 System.Byte OleDbType.UnsignedTinyInt
是 / 否 Boolean DBTYPE_BOOL System.Boolean OleDbType.Boolean
日期 / 时间 DateTime DBTYPE _ DATE System.DateTime OleDbType.date
货币 十进制 DBTYPE_NUMERIC System.Decimal OleDbType.numeric
十进制数: 十进制 DBTYPE_NUMERIC System.Decimal OleDbType.numeric
双数: 双 DBTYPE_R8 System.Double OleDbType.Double
Autonumber (复制 ID) GUID DBTYPE_GUID System.Guid OleDbType.guid
复制 (ID) 号: GUID DBTYPE_GUID System.Guid OleDbType.guid
Autonumber (长整型) 整数 DBTYPE_I4 System.Int 32 OleDbType.integer
数量: (长整型) 整数 DBTYPE_I4 System.Int 32 OleDbType.integer
OLE 对象 LongVarBinary DBTYPE_BYTES 数组 System.Byte OleDbType.LongVarBinary
单个数字: 单个 DBTYPE_R4 System.Single OleDbType.single
整型数: SmallInt DBTYPE_I2 System.Int 16 OleDbType.SmallInt
二进制 VarBinary * DBTYPE_BYTES 数组 System.Byte OleDbType.binary
超链接 VarWChar DBTYPE _ WSTR System.String OleDbType.VarWChar

 

### 路由传参的实现方式 在现代前端框架中,路由传参是一种常见的需求。以下是几种主流框架中实现路由传参的方式: #### Vue.js 中的路由传参 Vue Router 提供了多种方式来传递参数[^1]。可以通过以下三种方法实现: 1. **路径参数(Path Params)**:在路由配置中使用动态段(`:paramName`),并在导航时将参数值附加到路径中。 ```javascript const routes = [ { path: '/user/:id', component: User } ]; ``` 在导航时可以这样写: ```javascript this.$router.push({ name: 'User', params: { id: 123 } }); ``` 这种方式适用于需要将参数嵌入 URL 的场景。 2. **查询参数(Query Params)**:通过 `?key=value` 的形式附加到 URL 后面。 ```javascript this.$router.push({ path: '/user', query: { id: 123 } }); ``` 结果 URL 将是 `/user?id=123`,这种方式适合传递非敏感信息。 3. **路由组件 Props**:通过设置路由的 `props` 属性为 `true` 或对象,可以直接将参数作为 props 传递给组件。 ```javascript const routes = [ { path: '/user/:id', component: User, props: true } ]; ``` #### Flutter 中的路由传参 Flutter 提供了静态路由和动态路由两种方式来实现页面跳转与参数传递[^3]。 1. **静态路由**:通过 `routes` 配置实现页面跳转,但不支持直接传递参数。 ```dart class RoutePage extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: "route_index", home: MyRouteMainPage(title: 'Route inedex Page'), routes: <String, WidgetBuilder> { '/router/routeone': (_) => new RoutOnePage(), }, ); } } ``` 如果需要返回数据,可以使用 `Navigator.of(context).pop(value)` 和 `.then()` 方法处理返回值。 2. **动态路由**:通过 `Navigator.push` 方法实现带参数的页面跳转。 ```dart Navigator.of(context).push( MaterialPageRoute(builder: (context) => DetailPage(id: 123)), ); ``` 在目标页面中可以通过构造函数接收参数。 #### 搜索框场景中的路由传参 如果是在搜索框中输入内容并触发路由跳转,可以参考以下代码[^4]: ```javascript this.$router.push({ path: '/search', query: { q: this.searchInput } // 将搜索框内容作为查询参数 }); ``` 这种实现方式简单直观,适合用于表单提交或链接生成等场景。 ### 总结 不同的框架提供了多种路由传参方式,开发者可以根据实际需求选择合适的方法。路径参数适合用于 SEO 或书签功能,查询参数适合传递临时性或非敏感数据,而组件 Props 则更适合内部通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值