--Table: Member CREATE TABLE [dbo].[Member]( [MemberId] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](50) NULL, [CreateDate] [datetime] NULL, CONSTRAINT [PK_Member] PRIMARY KEY CLUSTERED ( [MemberId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO --Table LoginRecord CREATE TABLE [dbo].[LoginRecord]( [RecordId] [int] IDENTITY(1,1) NOT NULL, [MemberId] [int] NULL, [CreateDate] [datetime] NULL, CONSTRAINT [PK_LoginRecord] PRIMARY KEY CLUSTERED ( [RecordId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
這裡我們要查詢登錄的記錄,輸入的參數有
- MemberID: 帳號
- Name: 姓名
- StartLoginDate/EndLoginDate:登錄起訖
- StartCreateDate/EndCreateDate:資料建立起訖
有這四組的條件,至少會輸入一的條件,條件是以AND來組合,如果沒輸入的條件,就不會加入AND條件篩選,這如果以.net程式是非常好解決的,以下例子為了防止SQL INJECTION使用Parameter
// 假設已經資料庫連線
System.Text.StringBuilder sbSQL = new StringBuilder(500);
List<SqlParameter> cParameters = new List<SqlParameter>();
// 增加一個 1 = 1 的預設條件以便可以不需先判斷是否已經有條件,
//要不要前面加AND, 而可以順序任意加入條件
sbSQL.Append(select * from Member m inner join LoginRecord l on m.MemberId =
l.MemberId WHERE 1 = 1 ");
if (!String.IsNullOrEmpty(txtCondition1.Text)) {
sbSQL.Append(" m.name like @Column1");
cParameters.Add(new SqlParameter("@Column1", txtCondition1.Text));
}
if (!String.IsNullOrEmpty(txtCondition1.Text ||
!String.IsNullOrEmpty(txtCondition1.Text ) )
{
sbSQL.Append(" l.CreateDate between @Column2 and @Column3");
cParameters.Add(new SqlParameter("@Column2", txtCondition2.Text));
cParameters.Add(new SqlParameter("@Column2", txtCondition3.Text));
}
SqlCommand oCommand = new SqlCommand(sbSQL.ToString, conn);
if (cParameters.Count != 0)
{
oCommand.Parameters.AddRange(cParameters.ToArray());
}
但是如果要把參數都傳入Stored Procedure,要怎麼做呢?
這邊可以借助IsNull參數,來傳斷傳入的參數是否為Null,如果是Null就令其=要篩選的變數,跟1 = 1一樣,這個條件是ByPass的意思, 以MemberID為例,如果@MemberID 是null,條件就會變成Member = Member,一定會成立,就等於沒作用的條件,以下是完整的 Code
Alter procedure SP_GetMember
@MemberId int,
@Name nvarchar(50),
@StartLoginDate datetime,
@EndLoginDate datetime,
@StartCreateDate datetime,
@EndCreateDate datetime
as
select * from Member m inner join LoginRecord l on m.MemberId = l.MemberId
where
( m.name like '%' + isnull(@Name,'') + '%') and
m.MemberId = Isnull(@MemberId, m.MemberId) and
l.CreateDate >= IsNull(@StartLoginDate, l.CreateDate) and
l.CreateDate <= Isnull(@EndLoginDate,l.CreateDate) and
m.CreateDate >= IsNull(@StartCreateDate, m.CreateDate) and
m.CreateDate <= Isnull(@EndCreateDate,m.CreateDate)
http://www.codeproject.com/Articles/21234/Implementing-Dynamic-WHERE-Clause-in-Static-SQL
沒有留言:
張貼留言