2010年11月24日 星期三

在GridView裡合併儲存格

GridView裡合併相同內容的儲存格,是常有的需求。
以下的範例可選擇多個需要合併的欄位:(在PreRender事件裡處理)

protected void gv_PreRender(object sender, EventArgs e)
{
int[] mergeColumns = { 0 }; //要合併的欄位-編號(款)

foreach (int mergeColumn in mergeColumns)
{
int i = 1;

// 取得來源GridView
GridView gv = (GridView)sender;

if (gv!= null)
{
foreach (GridViewRow row in gv.Rows)
{
row.Cells[mergeColumn].RowSpan = 0;

if (row.RowIndex != 0)
{
if (row.Cells[mergeColumn].Text.Trim() == gv.Rows[(row.RowIndex - i)].Cells[mergeColumn].Text.Trim())
{
gv.Rows[(row.RowIndex - i)].Cells[mergeColumn].RowSpan += 1;
row.Cells[mergeColumn].Visible = false;
i += 1;
}
else
{
row.Cells[mergeColumn].RowSpan += 1;
i = 1;
}
}
else
{
row.Cells[mergeColumn].RowSpan = 1;
}
}
}
}
}

2010年11月23日 星期二

由xml到table

SQL 2005提供xml的支援,其中包括xml的data type,使用範例如下:

DECLARE @xml xml
SET @xml = N'<polist>
<po><ponumber>100</ponumber><podate>2008-09-10</podate></po>
<po><ponumber>101</ponumber><podate>2008-09-11</podate></po>
</polist>'
SELECT
doc.col.value('ponumber[1]', 'nvarchar(10)') ponumber
,doc.col.value('podate[1]', 'datetime') podate
,doc.col.value('poxml[1]', 'nvarchar(4000)') poxml
FROM @xml.nodes('/polist/po') doc(col)


只要再加入insert語法,就可以從xml參數理讀取資料,存到資料表了。

2010年9月28日 星期二

2009年7月28日 星期二

For XML Path

SQL Server 中利用這個語法可以將查詢的結果轉換成XML data,常用的語法如下

SELECT ns_signname
FROM signorg
WHERE signorg.seqsn= 111
FOR XML PATH('')

這個語法會將所有查詢結果組成一個字串,效果就像之前的string concatenation

詳細說明可以參考http://it.dianping.com/sql-for-xml-path.htm

2009年6月8日 星期一

Schema Comparison

最近接了一個需要維護的系統,接到的時候傻眼,測試區與上線區的schema是不一樣的,而且沒有文件註明哪裏有新增或是修改過,沒關係,天助自助者,寫個script來看看吧!

首先查詢看看測試區的table名稱

select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_TYPE = 'BASE TABLE'

將結果暫存後,再根據每個table名稱(暫存入參數@table),查詢是否有column的設定不一致的

SELECT TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS as col
WHERE TABLE_NAME = @table and (
col.COLUMN_NAME not in (
select COLUMN_NAME
from 上線區資料庫.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table) or
col.DATA_TYPE <> (
select DATA_TYPE
from 上線區資料庫.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table and COLUMN_NAME = col.COLUMN_NAME) or
col.CHARACTER_MAXIMUM_LENGTH <> (
select CHARACTER_MAXIMUM_LENGTH
from 上線區資料庫.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table and COLUMN_NAME = col.COLUMN_NAME) or
col.COLUMN_DEFAULT <> (
select COLUMN_DEFAULT
from 上線區資料庫.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table and COLUMN_NAME = col.COLUMN_NAME) or
col.IS_NULLABLE <> (
select IS_NULLABLE
from 上線區資料庫.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @table and COLUMN_NAME = col.COLUMN_NAME))

嗯,果然跳出一堆...

MCSE chapter 5 sec 1

2008年8月24日 星期日

SqlDataSource Output Parameter

如果在SqlDataSource裡面使用SelectCommand,InsertCommand,或是UpdateCommand,呼叫stored procedure,我們可以再OnSelected,OnInserted,OnUpdated事件中用output parameter來擷取stored procedure的回傳值,但是如果使用DeleteCommand並且試圖在OnDeleted事件中擷取回傳的output parameter時, 我們會發現,output parameter的值並沒有被改變,換句話說,只有output parameter在與DeleteCommand合用時,沒有辦法發生作用.例如:在以下的範例中,@rtn_code的質便不會被傳回.

protected void ds_activity_base_Deleted(object sender, SqlDataSourceStatusEventArgs e)
{
System.Data.Common.DbCommand cmd = e.Command;

if (cmd.Parameters["@rtn_code"].Value != null && cmd.Parameters["@rtn_code"].Value.ToString() == "0")
ClientScript.RegisterStartupScript(this.GetType(), "error", "alert('國際活動已成功刪除!');location.href='activity_CaseEntry.aspx';", true);
}


註:造成這種情形的原因,我並不清楚,同樣的問題,之前似乎有report回Microsoft過(見http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105193)但是看情形並未受到重視,也不清楚後來是如何解決的...

雖然無法解釋為何只有DeleteCommand會出現這種情形,但是的確有個方法可以work around這個問題,便是在OnDeleting事件中,將此output parameter的方向再次設定為ParameterDirection.Output,如下:

protected void ds_activity_base_Deleting(object sender, SqlDataSourceCommandEventArgs e)
{
System.Data.Common.DbCommand cmd = e.Command;

if (cmd.Parameters["@rtn_code"] != null)
cmd.Parameters["@rtn_code"].Direction = ParameterDirection.Output;
}