SqlParameter的用法


 關於Sql注入的基本概念,相信不需多說,大家都清楚,經典的注入語句是' or 1=1--
單引號而截斷字符串,“or 1=1”的永真式的出現使得表的一些信息被暴露出來,如果sql語句是select * from 的話,可能你整個表的信息都會被讀取到,更嚴重的是,如果惡意使用都使用drop命令,那么可能你的整個數據庫得全線崩潰。

當然,現在重點不是講sql注入的害處,而是說說如何最大限度的避免注入問題。

sql注入的存在在最大危害,是sql的執行語句沒有和控制語句分開,我們想要select一些東西,但用戶可能拼出' or 1=1甚至再加上delete/update/drop,后來是屬於控制語句了,所以要避免sql的注入,就必須把查詢語句與控制語句分開。

SqlParameter給我們提供了一個很好的類,有了它,我們可以不現拼接字符串,也可以不再擔心單引號帶來的慘劇,因為,這一切會有人來為我們完成的。

簡單的給個示例

傳統的查詢語句的sql可能為
string sql="select * from users where user_id='"+Request.QueryString["uid"]+"'";
很顯然,我們在這里拼接了字符串,這就給sql注入留下了可乘之機。

現在,我們要改寫這樣的語句,使用SqlParameter來做

SqlCommand SqlCmd = new SqlCommand(sql, SqlConn);
SqlParameter _userid = new SqlParameter("uid", SqlDbType.Int);
_userid.Value = Request.QueryString["u_id"];
SqlCmd.Parameters.Add(_userid);

這樣,我們可以保證外接參數能被正確的轉換,單引號這些危險的字符也會轉義了,不會再對庫造成威脅。

當然,這僅是一個示例而已,在真實的情況下,可能你還要對 Request.QueryString["u_id"]進行必要的檢測與分析,這樣才安全

所以,使用參數化的sql語句,是一種很好的做法

 

Dim sql As StringBuilder = New StringBuilder()
            sql.Append("")
            sql.Append("SELECT * FROM test")
            sql.Append(" WHERE  a= @p1 ")           

            Dim command As SqlCommand    =    dac.CreateCommand(sql.ToString())  'dac為自己寫的類
            Dim param As SqlParameter = New SqlParameter()
            param .ParameterName = "@p1"
            param .SqlDbType = SqlDbType.NVarChar
            param .Value = b       'b為該函數的參數(ByVal b as String)
            command .Parameters.Add(param)
            Dim reader As SqlDataReader = command.ExecuteReader()

 

 

SqlParameter 構造函數

SqlParameter 構造函數 (String, SqlDbType, Int32, ParameterDirection, Byte, Byte, String, DataRowVersion, Boolean, Object, String, String, String)
初始化 SqlParameter 類的一個新實例,該類使用參數名、參數的類型、參數的長度、方向、精度、小數位數、源列名稱、DataRowVersion 值之一、用於源列映射的布爾值、SqlParameter 的值、此 XML 實例的架構集合所在的數據庫的名稱、此 XML 實例的架構集合所在的關系架構以及此參數的架構集合的名稱。
命名空間: System.Data.SqlClient
程序集: System.Data(在 system.data.dll 中)

C#
public SqlParameter (
    string parameterName,
    SqlDbType dbType,
    int size,
    ParameterDirection direction,
    byte precision,
    byte scale,
    string sourceColumn,
    DataRowVersion sourceVersion,
    bool sourceColumnNullMapping,
    Object value,
    string xmlSchemaCollectionDatabase,
    string xmlSchemaCollectionOwningSchema,
    string xmlSchemaCollectionName
)


參數
parameterName
要映射的參數的名稱。

dbType
SqlDbType 值之一。

size
參數的長度。

direction
ParameterDirection 值之一。

precision
要將 Value 解析為的小數點左右兩側的總位數。

scale
要將 Value 解析為的總小數位數。

sourceColumn
源列的名稱。

sourceVersion
DataRowVersion 值之一。

sourceColumnNullMapping
如果源列可為空,則為 true;如果不可為空,則為 false。

value
一個 Object,它是 SqlParameter 的值。

xmlSchemaCollectionDatabase
此 XML 實例的架構集合所在的數據庫的名稱。

xmlSchemaCollectionOwningSchema
包含此 XML 實例的架構集合的關系架構。

xmlSchemaCollectionName
此參數的架構集合的名稱。

 備注
如果未在 size 和 precision 參數中顯式設置 Size 和 Precision,則從 dbType 參數的值推斷出它們。

SqlParameter 類
表示 SqlCommand 的參數,也可以是它到 DataSet 列的映射。無法繼承此類。

有關此類型所有成員的列表,請參閱 SqlParameter 成員。

System.Object
   System.MarshalByRefObject
      System.Data.SqlClient.SqlParameter

[Visual Basic]
NotInheritable Public Class SqlParameter
   Inherits MarshalByRefObject
   Implements IDbDataParameter, IDataParameter, ICloneable
[C#]
public sealed class SqlParameter : MarshalByRefObject,
   IDbDataParameter, IDataParameter, ICloneable
[C++]
public __gc __sealed class SqlParameter : public
   MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
[JScript]
public class SqlParameter extends MarshalByRefObject implements
   IDbDataParameter, IDataParameter, ICloneable
線程安全
此類型的所有公共靜態(Visual Basic 中為 Shared)成員是線程安全的。但不保證任何實例成員是線程安全的。

備注
參數名稱不區分大小寫。

示例
[Visual Basic, C#, C++] 下面的示例通過 SqlDataAdapter 中的 SqlParameterCollection 集合創建 SqlParameter 的多個實例。這些參數用於從數據源中選擇數據並將數據放在 DataSet 中。此示例假定已經用適當的架構、命令和連接創建了 DataSet 和 SqlDataAdapter。

[Visual Basic]
Public Sub AddSqlParameters()
    ' ...
    ' create myDataSet and myDataAdapter
    ' ...
    myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", SqlDbType.VarChar, 80).Value = "toasters"
    myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", SqlDbType.Int).Value = 239
   
    myDataAdapter.Fill(myDataSet)
End Sub 'AddSqlParameters

[C#]
public void AddSqlParameters()
{
// ...
// create myDataSet and myDataAdapter
// ...

  myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", SqlDbType.VarChar, 80).Value = "toasters";
  myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", SqlDbType.Int).Value = 239;
  myDataAdapter.Fill(myDataSet);

}

[C++]
public:
void AddSqlParameters()
{
// ...
// create myDataSet and myDataAdapter
// ...

  myDataAdapter->SelectCommand->Parameters->Add(S"@CategoryName", SqlDbType::VarChar, 80)->Value = S"toasters";
  myDataAdapter->SelectCommand->Parameters->Add(S"@SerialNum", SqlDbType::Int)->Value = __box(239);
  myDataAdapter->Fill(myDataSet);

}

[JScript] 沒有可用於 JScript 的示例。若要查看 Visual Basic、C# 或 C++ 示例,請單擊頁左上角的“語言篩選器”按鈕 。

要求
命名空間: System.Data.SqlClient

平台: Windows 98, Windows NT 4.0, Windows ME, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 系列, .NET Framework 精簡版

程序集: System.Data (在 System.Data.dll 中)

使用SqlParameter

SqlParameter[] p =
{
SqlHelper.MakeInParam("@EntryID",SqlDbType.Int,4,ev.EntryID),
SqlHelper.MakeInParam("@BlogID",SqlDbType.Int,4,ev.BlogID),
SqlHelper.MakeInParam("@URL",SqlDbType.NVarChar,255,DataHelper.CheckNull(ev.ReferralUrl)),
SqlHelper.MakeInParam("@IsWeb",SqlDbType.Bit,1,ev.PageViewType)
};
SqlHelper.ExecuteNonQuery(conn,CommandType.StoredProcedure,"blog_TrackEntry",p);

答疑:SqlParameter賦值之后怎么添加值
用SqlCommand我知道用add
但我想問的是   SqlParameter
例如
SqlParameter   parm   =   new   SqlParameter(PARM_ORDER_ID,   SqlDbType.Int);
parm.Value   =   orderId;
之后能不能再改parm添加一個值
因為我寫了個方法是傳遞SqlParameter類型的參數
但有時要做些判斷

SqlParameter   parm   =   new   SqlParameter(PARM_ORDER_ID,   SqlDbType.Int);
parm.Value   =   orderId;
if(...)
{
//添加一個參數
}
ExecuteReader(parm,.....);
請問應該怎么做呢
 
最佳答案        int IArticle.Insert(ArticleInfo article)
        {
            //如果對象存在
            if (article.ID != -1)
                return -1;
            else
                article.ID = TableHelper.GetSequence(SQLHelper.ConnectionString, "Article", "ID");
            //統計執行成功的數量
            int successCount = 0;
            string SQL_THIS = SQL_INSERT_ARTICLE;
            SqlParameter[] paras = GetParas();
            paras[0].Value = article.ID;
            paras[1].Value = article.Title;
            paras[2].Value = article.DateAdded;
            paras[3].Value = article.Text;
            paras[4].Value = article.SourceUrl;
            paras[5].Value = article.PostType;
            paras[6].Value = article.Author;
            paras[7].Value = article.Email;
            paras[8].Value = article.SourceName;
            paras[9].Value = article.BlogID;
            paras[10].Value = article.CategoryID;
            paras[11].Value = article.Summary;
            paras[12].Value = article.IsBySummary;
            paras[13].Value = article.DateUpdated;
            paras[14].Value = article.TitleUrl;
            paras[15].Value = article.FeedBackCount;
            paras[16].Value = article.PostConfig;
            paras[17].Value = article.EntryName;
            paras[18].Value = article.KeyWord;
            SqlConnection conn = new SqlConnection(SQLHelper.ConnectionString);
            successCount = SQLHelper.ExecuteNonQuery(conn, CommandType.Text, SQL_THIS, paras);

            return successCount;
        }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM