本文目录
目录
*1.发现的问题
*2.定义一个Users表[用户表]
*3.创建Users类
*4.MSSQL和Oracle中的参数传值
*5.总结
1.发现的问题
在C#里面,以前写数据库查询方面的东西基本上就是拼接字符串(判断一下没有关键字就行了),现在在C#连接Oracle中拼接使用参数,但是发现总会提示错误:
错误1:插入数字无效;
错误2:”mydb”失败,没有可用的错误消息,结果代码:DB_E_BADORDINAL(0X80040E55)
总算知道错误原因了。Sql中参数用@,而Oracle语句中参数用?,而且,插入数据库的字符真的需要不少区别。
做一个例子:
例子:
2.定义一个Users表[用户表]
MSSQL中:
Create table Users
(
id int,
name varchar,
pwd varchar,
dates datetime
)
Oracle中:
Create table Users
(
id number,
name varchar2(10),
pwd varchar2(10),
dates date
)
3.创建Users类
public class Users
{
public int id { get; set; }
public string username { get; set; }
public string pwd { get; set; }
public DateTime dates { get; set; }
}
4.MSSQL和Oracle中的参数传值
增加一个方法,改方法指定增加 Users 数据,
MSSQL:
public bool AddOneUser(Users user)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("insert into test1(id,username,pwd,dates) ");
strSql.Append("values(@id,@username,@pwd,@dates)");
//注意里面的@,PS:千万不能加上单引号!什么都别加,切记!!!
SqlParameter[] para = new SqlParameter[]{
new SqlParameter("@id",SqlDbType.Int),
new SqlParameter("@username",SqlDbType.VarChar),
new SqlParameter("@pwd",SqlDbType.VarChar),
new SqlParameter("@dates",SqlDbType.DateTime)
};
para[0].Value = user.id;
para[1].Value = user.username;
para[2].Value = user.pwd;
para[3].Value = user.dates;
int ret = SqlHelper.ExecuteNonQuery(CommandType.Text, strSql.ToString(), para);//别忘了para得带入诶
if (ret > 0)
{
return true;
}
else
return false;
}
Oracle:
public bool AddOneUser(Users user)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("insert into test1(id,username,pwd,dates) ");
strSql.Append("values(to_number(?),?,?,to_date(?,'yyyy-mm-dd hh24:mi:ss'))");
//注意?
OleDbParameter[] para = new OleDbParameter[]{
new OleDbParameter("@id",OleDbType.VarChar),
new OleDbParameter("@username",OleDbType.VarChar),
new OleDbParameter("@pwd",OleDbType.VarChar),
new OleDbParameter("@dates",OleDbType.VarChar)
};
para[0].Value = user.id;
para[1].Value = user.username;
para[2].Value = user.pwd;
para[3].Value = user.dates;
int ret = OracleHelper.ExecuteNonQuery(CommandType.Text, strSql.ToString(), para);
if (ret > 0)
{
return true;
}
else
return false;
}
PS:
SqlParameter:表示 SqlCommand 的参数,也可以是它到 DataSet 列的映射。
OleDbParameter:表示 OleDbCommand 的参数,还可以表示它到 DataSet 列的映射
5.总结
①在MSSQL中,
1.定义的参数使用 @;
2.传参类型可以直接在 new SqlParameter(“@id”,SqlDbType.Int) 写出来就可以;
3.传参的不要 在 @id 之类的上面单引号,不管 @id 是什么数据类型;(PS:20131112更新,血的教训!!!)
②在Oracle中,
1.定义的参数使用 ?,可以用 ? 完全代替,诶,以前不知道。
2.传参类型可以在 new SqlParameter(“@id”,SqlDbType.Varchar) 写出来,发现这里直接写实在不好转换,把转换丢在PL/SQL语句里面方便点: to_number(?)
③安全性
以前喜欢拼接字符串,然后用一段代码过滤:
/// <summary>
/// 检查传入字符串是否包含sql语句
/// </summary>
/// <param name="str">传入字符串</param>
/// <returns>包含返回true,不包含返回false</returns>
public bool FilterSql(string str)
{
string word = "and|exec|insert|select|delete|update|chr|mid|master|or|truncate|char|declare|join|cmd";
if (str == null)
{
return false;
}
foreach (string i in word.Split('|'))
{
if (str.ToLower().IndexOf(i + " ") > -1 || (str.ToLower().IndexOf(" " + i) > -1))
{
return true;
}
}
return false;
}
才发现多么愚蠢:(传送门) 感谢 @冰麟轻武
select * from Users where id like '%'and(1=1)and'%'='%'
居然查出来全表,这样的语句自己居然以前没有看到。