2012年8月10日 星期五

續:SQL 資料轉行

SQL資料轉行之後
終於有時間上來補充動態轉換的方法了


declare @Items nvarchar(max),  --不重複的Item轉成欄位
 @sql nvarchar(max)  --將要執行的SQL語法

select @Items=ISNULL(@Items,'')+'['+Item+'],' from Table1 group by Item  --取出Table內不重複的Item
set @Items=SUBSTRING(@Items,0,len(@Items)) --去除最後一個逗號

--將原本語法與轉好的欄位合併成一個字串
set @sql ='
select Name,'+@Items+'
from
(
select Name,Item,Score from Table1
) t
PIVOT (max(Score) for Item in ('+@Items+')) as a'

exec sp_executesql @sql  --執行SQL語法


經過上述方法
就可以將動態資料做轉換動作了
但是很不巧的
這幾天被SA打槍
舒服
因為串字串下SQL語法會發生 SQL Injection 危險

SQL Injection可以參考
SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(上)
SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(下)

因此又再做了修改

SQL語法:
--取出原本的資訊,依Item給ID,ID為欄位名稱
select Name,DENSE_RANK() over(order by Item)as [rid],
 Item,Score into #tab
from Table1

--利用ID做轉換的動作
select * into #myResult from (select Name,rid,Score from #tab ) t 
PIVOT (max(Score) for rid in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) as a;

--刪除轉換後整欄都為NULL的欄位
begin
 declare @i as int,@colnum as int
 set @i=0;
 set @colnum=0;
 select @colnum=MAX(rid) from #tab

 select @i=SUM(case when [1] is null then 0 else 1 end) from #myResult group by [1];
 if @i<1
 begin
  ALTER TABLE  #myResult DROP COLUMN [1] 
 end 
 else
 begin
  update #myResult
  set [1]=0
  where [1] is null
 end 
 set @i=0
 select @i=SUM(case when [2] is null then 0 else 1 end) from #myResult group by [2];
 if @i<1
 begin
  ALTER TABLE  #myResult DROP COLUMN [2] 
 end
 else
 begin
  update #myResult
  set [2]=0
  where [2] is null
 end 
 ....(將欄位延伸到10,太多就不全貼) 
end

--回傳rid對應Item資料
select rid,Item from #tab group by rid,Item order by rid

--回傳轉換後資料
select * from #myResult

drop table #tab
drop table #myResult

CS語法:
 //首先我們要先建好一個DataTable來存放轉換後資料
 DataTable dt = new DataTable();
 dt.Columns.Add("Name");  //先放Name
 while (dr.Read())
 {
  dt.Columns.Add(dr["Item"].ToString());  //將第一組回傳的Table(Item)依序放入
 }
    
 dr.NextResult();  //準備開始接收第二組回傳的Table(轉換後)
                
 while (dr.Read())
 {
  DataRow dRow = dt.NewRow();  //將目前Read的資料放到DataRow
  int CellCount = dr.FieldCount;  //取得Field數
  for (int i = 0; i < CellCount; i++)  //將欄位依序放入
  {
   dRow[i] = dr[i].ToString();
  }
  dt.Rows.Add(dRow);  //將DataRow加入DataTable
 }
 dr.Close();

以上

回sql目錄
回首頁


2012年7月22日 星期日

如何在提示視窗中顯示 asp.net 控制項

今天聽眾表示說他想要在按鈕上讓滑鼠移過去,出現提視小視窗並讓 asp.net 的控制項 gridview 在裡面顯示。

此次用的資料庫為 northwind,如果您的內容不是控制項而是 HTML,您也可以更換內容,以下為程式碼:

<!--把下面代碼加到<head>與</head>之間-->
    <style type="text/css">
    <!--
    body {
        padding-left:50px;
    }
    a.tip {
        color:red;
        text-decoration: underline;
        position:relative;
    }
    a.tip span{
        display:none; 
    }
    a.tip:hover{
        cursor:hand;
    }
    a.tip:hover .popbox{
        display: block;
        position:absolute;
        padding:10px;
        /* width:100px; 
        height:30px; */
        background:#000000;
        left:60px;
        top:30px;
        color:#FFFFFF;
        text-decoration: none;
    }
    -->
    </style>

...
...
...


<a href="http://www.o-asp.com" class="tip">把滑鼠移上來試試!
    <span class="popbox">
    <!-- 顯示內容開始 -->
    
    
    <asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" 
        CellPadding="4" DataKeyNames="EmployeeID" DataSourceID="northwind" 
        ForeColor="#333333" GridLines="None">
            <AlternatingRowStyle BackColor="White" />
            <Columns>
                <asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" 
                    InsertVisible="False" ReadOnly="True" SortExpression="EmployeeID" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" 
                    SortExpression="LastName" />
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" 
                    SortExpression="FirstName" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
                <asp:BoundField DataField="Region" HeaderText="Region" 
                    SortExpression="Region" />
            </Columns>
            <EditRowStyle BackColor="#2461BF" />
            <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
            <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
            <RowStyle BackColor="#EFF3FB" />
            <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
            <SortedAscendingCellStyle BackColor="#F5F7FB" />
            <SortedAscendingHeaderStyle BackColor="#6D95E1" />
            <SortedDescendingCellStyle BackColor="#E9EBEF" />
            <SortedDescendingHeaderStyle BackColor="#4870BE" />
        </asp:GridView>
        
        <asp:SqlDataSource ID="northwind" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT [EmployeeID], [LastName], [FirstName], [City], [Region] FROM [Employees]">
    </asp:SqlDataSource>
    
    
    <!-- 顯示內容結束 -->
    </span>
    </a>

回aspnet目錄
回首頁

2012年7月12日 星期四

執行字串內javascript指令

今天工作上遇到,以下做個分享
問題:
A視窗傳FunName給B視窗,然後B視窗去執行A視窗FunName的Function

A.aspx
window.open(B.aspx?FunName=Test);

B.aspx
opener.[FunName]();

各位發現問題了嗎?
B視窗要怎麼將字串內的文字當成指令/Function執行呢?

解法1:
使用setTimeout去執行(setTimeout用法請自行查)
setTimeout("opener." + FunName+ "();",10);
.
.
.


這樣就可以去執行A視窗的Function
但問題來了
如果接下來動作是在A視窗的Function執行完成後才能繼續做
但因為
setTimeout是非同步執行
那最後資料就會不正確
更可能直接Error給你看
這時候該怎麼辦呢?

解法2:
先將完整指令存成字串,再用Eval()去執行
var strFun = "opener." + FunName+ "();";
Eval(strFun);
.
.
.


這樣就會執行完A的Function再執行下面動作

對此問題而言
以上2種方法都可以達到執行字串內javascript指令的動作
差別在於
setTimeout 同時並行、節省執行時間
Eval 執行延續、錯誤排除方便

以上提供給大家參考

回aspnet目錄
回首頁

2012年6月29日 星期五

wordpress 不同頁面顯示不同側欄

繼前一篇文章 wordpress 兩欄式改為三欄式 的這個鄉民又發問了,他需要在不同頁面顯示不同的側欄,後來我 google 了一下,大約 10 分鐘就能完成。請大家不要笑他。




1

首先,安裝一個外掛 「Widget logic」。

2

安裝完成並啟用後,每一個模組下方都會出現 Widget Logic 的區塊:

在這個區塊有一些語法可以使用:
  • is_home() - 主頁
  • is_single() - 文章頁
  • is_page() - 頁面
  • is_category() - 文章分類頁
  • is_tag() - 文章標籤頁
  • is_archive() - 文章歸檔頁
  • is_404() - 404頁面
  • is_search() - 搜尋頁面
  • is_feed() - 訂閱頁

當然,也可以用一些「和、或、否」的邏輯判斷來調整,例如:

|| 表示或,&& 表示和,! 表示否。
  • is_home() - 僅主頁顯示
  • !is_home() - 除主頁以外的頁面顯示
  • !is_category(5) - 僅在ID非5的分類顯示
  • is_home() || is_category('baked-goods') - 在主頁或名稱為baked-goods的分類顯示
  • is_page('about') 僅在關於頁顯示


引用 & 參考:
Widget Logic – 让 WordPress 不同页面显示不一样的侧边栏

回首頁

2012年6月28日 星期四

wordpress 兩欄式改為三欄式

昨天有一個鄉民碰到 wordpress 的問題蠻有創意的,就是要將預設主題佈景的欄位配置改為自訂的欄位配置,苦於對 wordpress 不了解,所以就將這個問題問我。

而剛升級為 wordpress 中學等級的我,要教幼稚園等級的他可以順便練練功 ( 不要笑他 )。

回歸主題,要將 wordpress 佈景主題兩欄式改為三欄式的每個動作雖然簡單,但必須要去了解這個動作會影響到哪一塊,不然網站掛掉就不要哭哭,所以在要動哪一個檔案前,先將那個檔案備份起來,這樣比較保險。

要改 wordpress 之前先拍一張正面照:

接下來依照以下的步驟做修改,但還是要依照各佈景主題配置的程式碼做調整。

1

在「後台」,外觀 > 主題編輯器,找尋 function.php ( 佈景函式庫 ) 做編輯,在這個檔案內,搜尋「register_sidebar」字樣,此時必須要針對側欄區做判斷,因為要將側欄區複製一塊再做版面配置。搜尋到側欄區的程式碼如下:
register_sidebar( array(
    'name' => __( 'Main Sidebar', 'twentyeleven' ),
    'id' => 'sidebar-1',
    'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    'after_widget' => "</aside>",
    'before_title' => '<h3 class="widget-title">',
    'after_title' => '</h3>',
) );
把這一段程式碼複製後貼在後面,將 id 改為唯一值,由於版面已經用到 sidebar-5,所以我將新區塊 id 命名為 sidebar-6,命名為 "次主邊欄"。
register_sidebar( array(
    'name' => __( '次主邊欄', 'twentyeleven' ),
    'id' => 'sidebar-6',
    'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    'after_widget' => "</aside>",
    'before_title' => '<h3 class="widget-title">hi',
    'after_title' => '</h3>',
) );
到 外觀 > 模組就會看到 "次主邊欄" 的區塊,並且可以拖曳模組進去,但於頁面上並無太大更動。

2

要讓你所新增的區塊 "次主邊欄" 在頁面上顯示,就要在 外觀 > 主題編輯器 找尋 sidebar.php ( 邊欄 ) 做編輯,其實檔案裡面已經很明顯地說明這一區塊在做 id 為 sidebar-1 的區塊內容,而動作只需要將它的程式碼在複製一份貼在後面,然後 id 命名為 sidebar-6:
<?php
/**
 * The Sidebar containing the main widget area.
 *
 * @package WordPress
 * @subpackage Twenty_Eleven
 * @since Twenty Eleven 1.0
 */

$options = twentyeleven_get_theme_options();
$current_layout = $options['theme_layout'];

if ( 'content' != $current_layout ) :
?>
  <div id="secondary" class="widget-area" role="complementary">
   <?php if ( ! dynamic_sidebar( 'sidebar-1' ) ) : ?>

    <aside id="archives" class="widget">
     <h3 class="widget-title"><?php _e( 'Archives', 'twentyeleven' ); ?></h3>
     <ul>
      <?php wp_get_archives( array( 'type' => 'monthly' ) ); ?>
     </ul>
    </aside>

    <aside id="meta" class="widget">
     <h3 class="widget-title"><?php _e( 'Meta', 'twentyeleven' ); ?></h3>
     <ul>
      <?php wp_register(); ?>
      <li><?php wp_loginout(); ?></li>
      <?php wp_meta(); ?>
     </ul>
    </aside>

   <?php endif; // end sidebar widget area ?>
  </div><!-- #secondary .widget-area -->
<?php endif; ?>
<?php
if ( 'content' != $current_layout ) :
?>
  <div id="third" class="widget-area" role="complementary">
   <?php if ( ! dynamic_sidebar( 'sidebar-6' ) ) : ?>

    <aside id="archives" class="widget">
     <h3 class="widget-title"><?php _e( 'Archives', 'twentyeleven' ); ?></h3>
     <ul>
      <?php wp_get_archives( array( 'type' => 'monthly' ) ); ?>
     </ul>
    </aside>

    <aside id="meta" class="widget">
     <h3 class="widget-title"><?php _e( 'Meta', 'twentyeleven' ); ?></h3>
     <ul>
      <?php wp_register(); ?>
      <li><?php wp_loginout(); ?></li>
      <?php wp_meta(); ?>
     </ul>
    </aside>

   <?php endif; // end sidebar widget area ?>
  </div><!-- #secondary .widget-area -->
<?php endif; ?>

3

最後只需要在 外觀 > 主題編輯器 中,去針對你這幾個區塊的 css 做更動,調整成想要的版型配置,就完成了。


展示一下最後完成的結果:



參考:
wordpress由两栏变三栏


回首頁

2012年6月22日 星期五

Ajax 於 ASP.NET 即時更新資料

瀏覽網頁通常都不喜歡頻繁的頁面刷新,我個人就是。

所以我用 Ajax 來做更新頁面的動作,讓他即時的在頁面上顯示資料,隨手建立兩個 aspx 檔案 ( Default.aspx、ReadData.aspx )。

Default.aspx : 鍵入資料並同時傳送資料給 ReadData.aspx ,接收 ReadData.aspx 傳回之資料,即時顯示於此頁面上。

ReadData.aspx : 依照傳遞參數顯示資料。

註:範例資料庫為北風 ( northwind ) 資料庫。

以下為原始碼:

ReadData.aspx - 將多餘程式碼都拿掉,否則另一頁面接收資料會顯示不出來。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ReadData.aspx.cs" Inherits="ReadData" %>


    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="gvData" runat="server">
            
        </asp:GridView>
    </div>
    </form>

ReadData.aspx.cs - 讀取資料庫資料並讓 GridView 接收顯示。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.Data;
using System.Data.SqlClient;

public partial class ReadData : System.Web.UI.Page
{
    string strConn = "Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True";
    string strQuery;
    string strID;
    SqlConnection connection;
    SqlCommand command;
    SqlDataAdapter adapter;
    DataTable dt;

    protected void Page_Load(object sender, EventArgs e)
    {
        if ( ( strID = Request.QueryString["ID"]) != null )
        {
            try
            {
                connection = new SqlConnection(strConn);
                command = new SqlCommand();

                strQuery = "SELECT EmployeeID [Employee ID], FirstName + ' ' + LastName [Full Name] FROM Employees WHERE EmployeeID=" + strID;

                command.CommandText = strQuery;
                command.Connection = connection;

                adapter = new SqlDataAdapter(command);
                dt = new DataTable();

                adapter.Fill(dt);

                gvData.DataSource = dt;
                gvData.DataBind();
            }
            catch (Exception ex) { }
        }

    }
}

Default.aspx - 利用 ajax 來讀取網址包含參數索回傳的網頁內容 ( 當然用 XML 最好 ),定時執行 javascript 來即時更新頁面內容 ( 以下為 2 秒更新一次 )。
<%@ Page Title="首頁" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeFile="Default.aspx.cs" Inherits="_Default" MaintainScrollPositionOnPostback="true" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    
    <script language="javascript" type="text/javascript">
        function cretateXMLHttpRequest() {
            
            if (window.XMLHttpRequest) { // 如果是 Mozilla, Safari,...
                http_request = new XMLHttpRequest();
            }
            else if (window.ActiveXObject) { // 如果是 IE
                try {
                    // IE 又分成新版和舊版的,其處理方式也不同
                    // 新版的 IE,目前 IE 9 OK
                    http_request = new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch (e) {
                    try {
                        // 舊版的 IE
                        http_request = new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    catch (e) { }
                }
            }


        }

        function doStart() {
            cretateXMLHttpRequest();

            var id = document.getElementById('<%= txtID.ClientID %>').value;

            if (id != "") {

                var url = "ReadData.aspx?ID=" + id;
                http_request.open("GET", url, false);
                http_request.send(null);

                var show = document.getElementById('show');
                show.innerHTML = http_request.responseText;
                

            }
            setTimeout(doStart, 2000);

            // alert(id);
        }
    </script>


</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    

    <asp:TextBox ID="txtID" runat="server"></asp:TextBox>

    <div id="show"></div>
    
    <script language="javascript" type="text/javascript">
        doStart();
    </script>
</asp:Content>

執行結果如下圖:


引用 & 參考:
AJAX 入門:第一個範例
AJAX核心-XMLHttpRequest[筆記]

回aspnet目錄
回首頁


2012年6月15日 星期五

wordpress 修改語言檔

wordpress 和 blogger 一樣都是屬於 CMS 類的系統,如果是在 wordpress 官網申請一個空間使用這套系統,那我會覺得它會比 blogger 還不好用,因為它有些功能是需要付費的;但如果是用自己的空間架設 wordpress 的話,那就大不相同了,因為 wordpress 的自製化以及擴充模組和佈景主題實在是太好用了,雖然我曾經有安裝過一個佈景主題把整個網站弄掛,我不清楚是我使用上的問題還是系統的問題,但我相信只要使用者認為正確使用,所有的問題都可以推究系統 ( 似乎好像在很多地方都是這樣 )。

以下圖片是各大 CMS 在美國的使用程度:

圖片來源:WordPress completely dominates top 100 blogs

果然是自己空間架設 wordpress 佔絕大多數,反而是 blogger 只有 2%,也就是說,現在 wordpress 除了方便使用之外,也有很多人在開發方便使用的模組。

我在使用 wordpress 時,碰到一些預設的文字無法在後台修改,就要找 wordpress 的預設語言檔,路徑如以下圖片所示:


內有四個檔案,ms-zh_TW.po、ms-zh_TW.mo、zh_TW.po、zh_TW.mo,我們先要有一個概念,po 檔案等於原始碼,mo 檔案等於編譯過後的執行檔,為一個二進位檔,也就是說,系統語言檔只需要讀取 mo 檔。

編輯 po 有一個方便的軟體可以使用「poedit」,可以到poedit 網站下載,po 檔就會變成以下圖示:


假設要將首頁的連結文字由「首頁」換成「Home」:


可以將 zh_TW.po 檔開啟找尋「首頁」:


接著在此行點擊右鍵再點擊「將原文內容複製到譯文欄位去」



就會將文字「首頁」換成「Home」,然後儲存,它會自動產生一個 mo 檔案,接著再將這兩個檔案覆蓋回去再重新整理網頁,就會如以下圖所示:


回首頁




2012年6月14日 星期四

SQL excel 檔案查詢以及定序問題的解決

今天 User 給我一個 excel,要求我不但將實體檔案做更名,連同資料庫紀錄的路徑也一起更新。

此時就必須做到 excel 檔案與實體資料表的查詢。

我利用 OPENROWSET 語法將 excel 資料轉成資料表,例如以下程式碼:

SELECT *
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0;Database=檔案位置;HDR=YES;IMEX=1','SELECT * FROM [Sheet1$]') AS O
INNER JOIN Product P ON P.ID  = O.ID  

利用實體檔案 ( excel ) 與檔案資料表 ( *.xls ) 的關聯欄位做合併查詢 ( INNER JOIN ),然後就出現以下錯誤訊息:

Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_Taiwan_Stroke_CI_AS" in the equal to operation.

後來 google 一下才知道這是定序的問題。

最後只需要在欄位後面加上 collate Chinese_Taiwan_Stroke_CI_AS,對應到另一個資料表的定序即可。



2012/06/18 AM 10:28 KaiYai 補充:


下面KaiYai也來提供一下最近遇到的excel與資料庫問題

問題:從excel篩選出所需資料,做一些運算後Insert到資料庫
解法:
首先先做篩選與運算
我們將excel當成一個資料庫來使用(產生ConnectionString)
對其下SQL語法篩選資料
以下提供一個class

public class ReadExcel
{
    /// <summary>
    /// 讀取Excel資料
    /// </summary>
    /// <param name="File">Excel完整路徑</param>
    /// <param name="strCommand">SQL語法</param>
    public DataTable ReadExcelFile(string File, string strCommand)
    {
        DataTable dt = new DataTable();
        string sConnectionString = "";
        if (File.Substring(File.Length - 4, 4) == "xlsx")
        {
            sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + File + ";Persist Security Info=False;Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
        }
        if (File.Substring(File.Length - 3, 3) == "xls")
        {
            sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + File + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
        }

        if (sConnectionString != "")
        {
            OleDbConnection objConn = new OleDbConnection(sConnectionString);
            objConn.Open();
            OleDbCommand objCmdSelect = new OleDbCommand(strCommand, objConn);
            OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();

            objAdapter1.SelectCommand = objCmdSelect;
            DataSet objDataset1 = new DataSet();

            try
            {
                objAdapter1.Fill(objDataset1, "myExcel");
                dt = objDataset1.Tables["myExcel"];
            }
            catch
            {
            }
            finally
            {
                objConn.Close();
            }
        }
        return dt;
    }
}

接著要將資料傳到SQL SERVER
這邊我們使用預存類型與預存程序

預存類型:
USE [DataBase]
GO
CREATE TYPE [teb] AS TABLE(
 [No] [int],
 [Name] [nvarchar](20),
 [Address] [nvarchar](max),
 [Age] [int]
)
GO

預存程序:
USE [DataBase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [DataTableUpload]
@table teb READONLY  --宣告一個teb,後面一定要有READONLY
AS
insert into Member([No],[Name],[Address],[Age])
select [No],[Name],[Address],[Age]
from @table
GO

在使用上面,我是習慣用SQLObject
SQLObject obj = new SQLObject(ConfigurationManager.ConnectionStrings["Con"].ConnectionString);
SqlParameter[] pm = new SqlParameter[1];
pm[0] = new SqlParameter("@table", dt);
obj.ExeProcNon("DataTableUpload", pm);

這樣就大功告成了


回sql目錄
回首頁




2012年6月8日 星期五

SQL資料轉行

最近遇到SQL SERVER篩選資料時

需要將資料做列轉行(行轉列)的動作

問題:
篩選出每個人在指定 年/月 的每天工作時數

下圖中
上面的是原始資料儲存方式
下面是要秀出來的畫面


試了很多方式

最後找到SQL SERVER 2005以上才有支援的功能

SQL語法:



select 姓名,(case [1]when [1] then [1] else 0 end) as[1],
  (case [2]when [2] then [2] else 0 end) as[2],...
    --顯是最後結果
    --因為會有休假日,所以當該天為NULL則顯示
    from(
        select 姓名,day(日期) as 日期,工作時數
        --原始資料顯示為年-月-日,只顯示一個月的每天工作時數,所以只取日
        from 工作時數紀錄
        where year(日期) = 年and month(日期) = 月
    ) as t
    PIVOT
    (
        sum(工作時數)  --這邊是要顯示的資料,不能直接指定欄位名稱,可以用SUM或MAX等等來做
        for 日期in([1],[2],...)  --指定轉換的欄位名稱
    ) as p

先將資料篩選出來

再利用PIVOT去將資料做轉換

最後將轉換後資料顯示為結果

很輕鬆的就完成轉換的動作


注意:
for 欄位 in (欄位名稱1,欄位名稱2,欄位名稱3,....)
這邊括號內設定的欄位名稱要等於篩選出來的所有資料指定欄位內容一樣
如果不同就會顯示NULL
沒有設定到又不會顯示
所以當資料是很隨機的時候
就需要將語法轉成字串
並且在設定欄位的時候將隨機值指定為要顯示的欄位
然後再執行該字串

改天有空再補充進來

回sql目錄
回首頁



2012年6月1日 星期五

Mysql 出現亂碼的處理方式

最近在製作一隻 PHP 系統,遇到資料庫中文出現亂碼,但是在頁面上正常顯示,寫入更新都是亂碼。

由於 php.ini 內的預設編碼為 default_charset = "iso-8859-1",所以只要修改成與資料庫編碼相同的編碼即可,而我則改為 UTF-8。

另一種方法,就是在連結資料庫後加上 mysql_query('SET NAMES utf8'); 讓編碼成為 UTF-8 即可。

回 PHP 目錄
回首頁

2012年5月17日 星期四

PHP登入-使用 Bootstrap 美化

以下程式碼基於PHP研習中的實作練習下的管理者登入。

1. 先建立一個”admin”資料庫,並建立” manager”資料表,資料表中新增三欄位分別為「idno」”(主索引)、「 id」 char(12)、「pwd」 char(12)。

2. 在config.php內設定資料庫環境。
<?php
//======資料庫變數======//
$cfgDB_HOST = 'localhost';  //資料庫所在主機位置
$cfgDB_PORT ="3306";        //資料庫PORT(預設為3306)
$cfgDB_USERNAME ="hebe";    //資料庫帳號
$cfgDB_PASSWORD ="12345";   //資料庫密碼
$cfgDB_NAME = "admin";      //使用的資料庫
?>

3. connect.php插入config.php用來連結資料庫,並下選擇資料庫的指令。
<?php
// 建立資料庫連線
function create_connection()
{
    include 'config.php';
    $link = mysql_connect($cfgDB_HOST . ":" . $cfgDB_PORT, $cfgDB_USERNAME, $cfgDB_PASSWORD);
    return $link;
}

// 選擇資料庫
function execute_sql($cfgDB_NAME, $sql, $link)
{
    mysql_select_db($cfgDB_NAME, $link);
    $result = mysql_query($sql, $link);
    return $result;
}
?>

4. login.php為使用介面,以post方式送出。
(該範例使用Boostrap美化,使用過程可參考: Asp.net 的基本使用)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=big5">
    <link rel="stylesheet" type="text/css" href="bootstrap.css" /> 
</head>
<body>
<div class="span4" >
    <form action="check.php" method="post" > 
        <table class="table table-bordered"  >
            <tr>
                <th colspan="2">管理者登入</th>
            </tr>
            <tr>
                <td> 帳 號 </td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td> 密 碼 </td>
                <td><input type="password" name="pwd"></td>
            </tr>
            <tr>
                <td colspan="2">
                <input type="submit" value="登入" class="btn btn-primary"></td>                        
            </tr>
        </table>      
    </form> 
</div>
</body>
</html>

5. check.php將login.php傳來兩欄位”id”及” pwd”值加以判斷帳密是否正確,若登入成功會以session方式暫存帳號並顯示於畫面中。
<?php 
//連結資料庫
    session_start();
    require_once("connect.php");
    $link = create_connection();
    $id = $_POST["id"]; //login.php傳來帳號欄位輸入值
    $pwd = $_POST["pwd"]; //login.php傳來密碼欄位輸入值
    $sql  =  "select id from manager where id='$id' and pwd='$pwd'";
    $rs   =  execute_sql("admin", $sql, $link);
    $total=   mysql_num_rows($rs);  
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>  
    <link rel="stylesheet" type="text/css" href="bootstrap.css" /> 
</head>
<body>
    <div class="span4" >
    <?php   
        //判斷所選取資料的數目是否大於0,若大於0則表示資料庫有這筆帳號和密碼,即登入成功
        if($total>0){
           $_SESSION['username'] = $id; 
           echo "歡迎" . $_SESSION['username'] . "登入成功!<br/>";
           echo '<a class="btn btn-danger btn-small" href="logout.php">登出</a>';
        } 
        
        else{ 
           echo "帳號或密碼輸入有誤,請再重試一次!<br/>";
           echo '<a class="btn btn-info btn-small" href="logout.php">返回</a>';
        }
    ?>   
    </div>
</body>
</html>

6. logout.php登出,清除session值。
<?php session_start(); ?>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php
//將session清空
unset($_SESSION['username']);
echo '登出中......';
echo '<meta http-equiv=REFRESH CONTENT=1;url=login.php>';
?>

完成圖


回 PHP 目錄
回首頁

2012年5月12日 星期六

PHP上傳檔案 - 使用 Boostrap 美化

這次小女子我來分享PHP上傳檔案的方法啦~~就請大家參考參考一下羅~ :D

以下程式碼基於PHP 研習中的實作練習下的檔案上傳程式碼。

1.

於config.php設定存放檔案的資料夾及檔案限制大小。
(須先自行於同目錄下建立"uploads"資料夾哦~)
<?php
//存放檔案的資料夾,這裡我是開一個「uploads」的資料夾來存放上傳的檔案。// 
$cfg_path =  "uploads/";

//上傳檔案大小限制,可根據自己的需求來作修改//
$cfg_max_size = 2*1024*1024;
?>    

2.

work.php以_FILES函數處裡文件上傳,並用move_uploaded_file()函數將資料上傳至指定資料夾中,其中還包含了上傳後的檔案命名。
<?php
include ("config.php");  //插入config.php

     //如果檔案上傳有錯誤,可以顯示錯誤代碼。
    if ($_FILES['upfile']['error'] > 0)
    {
        echo "Error: " . $_FILES['upfile']['error'] . "<br />"; 
    }
    else
    {
        //上傳檔案的原始名稱。
        $upfile_name = $_FILES['upfile']['name']; 
     //上傳的檔案原始大小。
        $upfile_size = $_FILES['upfile']['size']; 
     //上傳的檔案類型。
        $upfile_type = $_FILES['upfile']['type']; 
        //上傳檔案後的暫存資料夾位置。
        $upfile_tmp_name = $_FILES['upfile']['tmp_name'];  
    }
    
    //==== 檢查是否確實有上傳檔案 ====//     
    if($upfile_size==0){       
?>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=big5">
    </head>
    <body>
        <script language=javascript>
            alert("請確實選擇要上傳的檔案喔!");
            history.go(-1);  //返回
        </script>             
    </body>
</html>   
 <?php
 }

    //檢查上傳的檔案是否有超過限制的大小
    if($upfile_size>$cfg_max_size){          
?>
<html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=big5">
    </head>
    <body>
    <script language="javascript">
      alert("上傳檔案的大小不得超過 <? echo $cfg_max_size /1024/1024 ?> MB,\n請您重新上傳!");
      history.go(-1);                               
    </script>   
    </body>
</html>                             
<?php
    exit;
    }
    
    $yearDir = date("Y");
    $monthDir = date("m");
    $dayDir = date("d");
    
    $full_path = "$cfg_path" . "$yearDir/$monthDir/$dayDir/";
    $year_path = "$cfg_path" . "$yearDir/";
    $month_path = "$cfg_path" . "$yearDir/$monthDir/";
    
    //判定是否有建立"年","月","日" 資料夾,若沒有就建立資料夾
    if(!is_dir($year_path)) 
        mkdir($year_path);
    
    if(!is_dir($month_path))
        mkdir($month_path);
        
    if(!is_dir($full_path))
        mkdir($full_path);
    
    /*
    explode(separator,string,limit)
    separator     必需。規定在哪里分割字串。
    string     必需。要分割的字串。
    limit     可選。規定所返回的數組元素的最大數目。
    "a.b.c.d.png" => $file_name = abcd
                => $file_subname = png
    array[] {"a", "b", "c", "d", "png"} count = 5
    */
    $file_arr = explode(".", $_FILES['upfile']['name']);
    $file_subname = $file_arr[count($file_arr) - 1]; //副檔名
    
    $file_name = ""; 
    for ($i = 0; $i < count($file_arr) - 1; $i ++ )
        $file_name .= $file_arr[$i];
    
    //上傳後檔案命名
    $upfile_name = $file_name . '-' . date("His") . '.' . $file_subname; 
    
    //====== 檔案上傳至資料夾 =====//                 
    $cp = move_uploaded_file($upfile_tmp_name, "$full_path/$upfile_name");
            
        
    //判斷是否上傳成功
    if($cp)
    {
        echo "Upload Success!<br>";
        echo "檔案大小:".$upfile_size."<br>";
        echo "檔案名稱:".$upfile_name;                  
    }
    else
 {
        echo "Fail!";                   
    }              
?> 

3.

可至Apache資料夾下的bin資料夾中找到php.ini檔,將其date.timezone = UTC改成date.timezone = "Asia/Taipei",此動作是將時間改成台灣的標準時間,修改後將伺服器重新啟動即可。

4.

upload.php為使用介面程式碼,其中我為了美化整體畫面套用了Boostrap,你可至bootstrap 網站下載相關.css及.js檔。 ( 使用過程可參考:Bootstrap 於 Asp.net 的基本使用)
<?php
include ("config.php"); //插入config.php
?>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=big5">
    <link rel="stylesheet" type="text/css" href="bootstrap.css" /> 
    <script language="javascript">
    function checkform()
    {    
        if(document.thisform.upfile.value=='')
        {
            alert('您還沒選擇要上傳的檔案喔!')
            return false;
        }
        return true;
    }
    </script>
    </head>
    <body>
    <br><br>
    <center>
    <form action="work.php" method="post" enctype="multipart/form-data" name="thisform">
    ※上傳檔案大小以 <font color=red><?php echo $cfg_max_size/1024/1024; ?></font> MB 為限<br>
    <table ><tr><td>
    <table class="table table-striped table-bordered table-condensed">
      <tr>
        <td> 選擇檔案 </td>
        <td> <input type="file" name="upfile" class="input-file" size="20" /></td>
      </tr>
      <tr>
         <td>  
           <input type="hidden" name="work" value="upload" />
           <input type="submit" value="確定送出" onclick="return checkform()" class="btn btn-primary" />
         </td>
      </tr>
    </table>
    </td></tr></table>
    </form>
    </body>
</html> 


完成圖



回 PHP 目錄
回首頁



2012年5月10日 星期四

PHP 換頁 - 使用 Bootstrap 美化


大家好,我是一個將邁入社會的小姑娘,這幾天對PHP有了一點點小小的研究,那就是當你需要顯示大量資料時,畫面資料一大堆不知道該怎麼辦,此時可以用 PHP 換頁 的方式將資料分成好幾頁,以方便使用者閱讀。以下是我所適用的方法,希望對大家有所幫助~YA!!

以下程式碼基於 PHP 研習 中的實作練習下的資料換頁程式碼。

1. 

首先請至 Northwind for mysql 下載微軟範例資料庫北風 (northwind) 資料庫作為 PHP 換頁 的顯示資料,並將其匯入phpmyadmin中。




2. 

接著在config.php內設定資料庫環境。

<?php
    //======資料庫變數======//
    $cfgDB_HOST = 'localhost';     //資料庫所在主機位置
    $cfgDB_PORT ="3306";          //資料庫PORT(預設為3306)
    $cfgDB_USERNAME ="trista";    //資料庫帳號
    $cfgDB_PASSWORD ="trista";    //資料庫密碼
    $cfgDB_NAME = "northwind";    //使用的資料庫
?>


3. 

connect.php插入config.php用來連結資料庫,並下選擇資料庫的指令。

<?php
    // 建立資料庫連線
    function create_connection()
    {
        include 'config.php';
        $link = mysql_connect($cfgDB_HOST . ":" . $cfgDB_PORT, $cfgDB_USERNAME, $cfgDB_PASSWORD);
        return $link;
    }
    // 選擇資料庫
    function execute_sql($cfgDB_NAME, $sql, $link)
    {
        mysql_select_db($cfgDB_NAME, $link);
        $result = mysql_query($sql, $link);
        return $result;
    }
?>

4.

 
為了美化 PHP 換頁 整體畫面可至bootstrap 套用相關.css.js檔。
( 使用過程可參考:Bootstrap 於 Asp.net 的基本使用,如果還不會用,你們自己想辦法 )

5.

 
PHP 換頁範例中插入了connect.php連結資料庫,並以bootstrap美化畫面(我所使用的包含bootstrap.cssbootstrap-responsive.css),資料庫則是以北風資料庫做為範例。

<?php 
    // 資料庫連結
    require_once("connect.php");  
    $link=create_connection();  

    // 判斷Page傳來指定的頁數,以決定本頁顯示的資料
    if (isset($_POST['page']))
        $nowPage = $_POST['page'];
    
    if (!isset($nowPage)) 
        $nowPage = 1;

    // 判斷pern傳來的值,以決定顯示的資料筆數
    if (isset($_POST['pern']))
        $perNum = $_POST['pern'];
    
    if (!isset($perNum)) 
        $perNum = 5;  // 每頁顯示 5 筆(每次取5筆資料)
  
    //總筆數
    $sql = "select count(*) from nwsuppliers "; // 計算資料表 nwsuppliers 總筆數
    $rs = execute_sql("northwind", $sql, $link);  // 選擇資料庫 northwind
      list($totalNum) = mysql_fetch_row($rs);
  
    //若資料庫中無任何資料
    if($totalNum == 0)
    {
        echo "目前沒有資料";
        exit;
    }
  
    //開始起始指標
    $startId = ($nowPage - 1)* $perNum;
  
    //該頁實際顯示資料筆數目
    if(($startId+$perNum)>$totalNum) {
        $realPerNum = $totalNum - $startId;
    }else{
        $realPerNum = $perNum;
    }
  
    //總頁數
    if($totalNum % $perNum == 0){
        $totalPage = $totalNum / $perNum;
    }else{
        $totalPage = intval($totalNum / $perNum)+1;
    }
  
    //第一頁
    $firstPage=1;
  
    //最後一頁
    $lastPage = $totalPage;  
  
    //上一頁
    if($nowPage > 1){
        $forwardPage = $nowPage - 1;
        $firstPgLink = "<li><a href=\"javascript:chg(1, $perNum);\">第一頁</a></li>";
        $forPgLink = "<li><a href=\"javascript:chg($forwardPage, $perNum);\">《  </a></li>";
    }else{
        $forwardPage = false;
        $firstPgLink = "";
        $forPgLink = "";
    } 

    //下一頁
    if($nowPage < $totalPage){
        $nextPage = $nowPage + 1;
        $lastPgLink = "<li><a href=\"javascript:chg($lastPage, $perNum);\">最後一頁</a></li>";
        $nextPgLink = "<li><a href=\"javascript:chg($nextPage, $perNum);\"> 》 </a></li>";
    }else{  
        $nextPage =  false;
        $nextPgLink = "";
        $lastPgLink = "";
    }

?>
<!DOCTYPE html>
<html>
<head>
    <link type="text/css" rel="stylesheet" href="css/bootstrap.css">
        <script language="JavaScript">
            function chg(np, n){
                document.sd.page.value=np;
                document.sd.pern.value=n;
                document.sd.submit();
            }
        </script>
</head>
<body>
    <form action="page.php" method="post" name="sd">
        <input type="hidden" name="page"> 
        <input type="hidden" name="pern">   
    </form>

    <table class="table table-striped table-bordered table-condensed" align='center' >
        <tr align='center' > 
            <td nowrap width='80' >CompanyName </td> 
            <td nowrap width='100' >ContactName</td>
            <td nowrap width='100' >ContactTitle</td>
        </tr>
        <?php
            //取出資料欄位CompanyName , ContactName , ContactTitle
            $sql = " select  CompanyName ,  ContactName,  ContactTitle  from nwsuppliers ";
            $rs = execute_sql("northwind", $sql, $link);

            //顯示資料
            for($i=$startId;$i<$startId+$realPerNum;$i++){
                mysql_data_seek($rs,$i);
                list( $CompanyName ,  $ContactName, $ContactTitle ) = mysql_fetch_row($rs);
        ?>
        <tr align='center'>
            <td nowrap ><?php echo $CompanyName ;?></td>
            <td nowrap ><?php echo $ContactName;?></td>
            <td nowrap ><?php echo $ContactTitle;?></td>    
        </tr>
        <?php } ?>
    </table>
  
    <form>
        <div class="pagination pagination-centered">
        <ul>
            <?php echo $firstPgLink; //第一頁 ?> 
            <?php echo $forPgLink; //上一頁 ?>
            <?php 
                $limitPage = 2; //顯示該頁+-頁碼數
                $minPage = $nowPage - $limitPage < 1 ? 1 : $nowPage - $limitPage; //顯示最小頁碼
                $maxPage = $nowPage + $limitPage > $totalPage ? $totalPage : $nowPage + $limitPage; //顯示最大頁碼

                //顯示換頁頁碼
                for($x = $minPage ; $x <= $maxPage ; $x++)
                {
                    $li = "<li>";
                    if ($x == $nowPage)
                        $li = "<li class=\"active\">";
                    $PgLink = $li . "<a href=\"javascript:chg($x, $perNum);\">$x</a></li>";
                    echo $PgLink;
                }
            ?>
   
            <?php echo $nextPgLink; //下一頁 ?>
            <?php echo $lastPgLink; //最後一頁 ?>
            <li><a>共<?php echo $totalPage; //總頁數 ?>頁</a></li>
            <li><a>(<?php echo $totalNum; //總資料筆數 ?> 筆資料)</a></li>
            <li><a style="border-style: none;">
            <?php 
                if($totalPage == 1){ 
                    echo "";
                }
                //快速換頁下拉式選單
                else{     
                    $pageFast="<select name=\"pageFast\" onChange=\"chg(this.form.pageFast.value, this.form.perNum.value);\" style=\"width: 90px;\" >";
                    for($i=1;$i<=$totalPage;$i++){
                        $pageFast.="<option value=\"".$i."\"";
                    if($i==$nowPage) $pageFast.=" selected";
                    $pageFast.=">第".$i."頁</option>";        
                }             
                $pageFast.="</select>";
                echo $pageFast;
                }
            ?>       
                </a>
            </li>
            <li><a style="border-style: none;">

            <?php
     
                if ($totalPage == 1)
                {
                    $pagePerNum = "<select name=\"perNum\" onChange=\"chg(1, this.form.perNum.value);\" style=\"width: 110px;\" >";
                }
                else
                {
                    $pagePerNum = "<select name=\"perNum\" onChange=\"chg(this.form.pageFast.value, this.form.perNum.value);\" style=\"width: 110px;\" >";
                }
                $pnList = array(5, 10, 20, 50, 100, 200); //每頁所顯示的資料筆數
                $pnCount = count($pnList);
    
                //下拉式顯示資料筆數
                for ($i = 0; $i < $pnCount; $i ++)
                {
                    $pagePerNum .= "<option value=\"" . $pnList[$i] . "\"";
                    if($pnList[$i] == $perNum) $pagePerNum .= " selected";
                    $pagePerNum .= ">顯示" . $pnList[$i] . "筆</option>";    
                }
     
                $pagePerNum .= "</select>";
     
                echo $pagePerNum;
            ?>      
                </a>
            </li>
        </ul>
        </div>    
    </form>   
</body>
</html>

完成圖

回 PHP 目錄
回首頁



2012年5月7日 星期一

Jquery 子母頁面間的 json 參數傳遞

應某位聽眾請求,他需要了解如何在「母頁面開啟子頁面後,子頁面處理資料後,傳遞 json 資料給母頁面接收」,稍微寫了一下,其實不難,但是由於本人眼力似乎趨近於老人,所以變數錯了過了很久才發現,差不多弄了兩個小時才把它弄好,實際上,只需要 10 分鐘。

1.

首先先到 JQuery 官方網站下載最新的 js 檔 (目前版本為:v1.7.2)

2.

再到 rahul 網友發布的網誌 jQuery - Encode & Decode arbitrary objects to and from JSON 中,擷取他的 json 編碼與解碼的 js 檔案

3.

接著我寫兩個頁面,a.html 將 b.html 打開後,將 email 與 password 欄位輸入值後,點擊「確認」鍵後,即將這兩個欄位藉由 $.JSON.encode 函式將欄位值打包為 json 格式,再利用 window.opener 的屬性將 json 格式資料傳回 a.html 的 jsonstring 隱藏欄位,再呼叫 a.html 的 javascript 的函式將 jsonstring 隱藏欄位值讀取出並放入所在位置,這麼一來,問題就解決了

  • a.html


    <html>
    <head>
    
    
    <script type="text/javascript" src="jquery-1.7.2.min.js"></script>
    
    <script type="text/javascript">
        function show()
        {
            var encoded = $('#jsonstring').val();
            var obj = jQuery.parseJSON(encoded);
            
            $('#email').val(obj.email);
            $('#password').val(obj.password);
        }
    </script>
    </head>
    <body onload="abc();">
        <form name="form">
            <input type="text" id="email" name="email"/>
            <input type="text" id="password" name="password"/>
            
            <input type="hidden" id="jsonstring" name="jsonstring" />
            <br />
            <a href="b.html" target="_blank">b.html</a>
        </form>
    </body>
    </html>
  • b.html



    <html>
    <head>
    
    
    <script type="text/javascript" src="jquery-1.7.2.min.js" ></script>
    <script type="text/javascript" src="json2.js" ></script>
    
    <script type="text/javascript">
        function dosubmit(){
    
            var email = $('#email').val();
            var password = $('#password').val();
    
            var thing = {email: email, password: password};
    
            var encoded = $.JSON.encode(thing);  
    
            var decoded = $.JSON.decode(encoded);
    
            $('#jsonstring').val(encoded);
            window.opener.document.all.jsonstring.value = encoded;
            
            window.opener.show();
            
            this.close(); 
    
        }
    </script>
    
    </head>
    <body>
            <input type="text" id="email" name="email" />
            <input type="text" id="password" name="password" />
            <input type="button" onclick="dosubmit()" value="確認">
    
    </body>
    </html>

回JQuery目錄
回html目錄
回首頁


PHP 程式設計筆記目錄

  1. 架設 xoops 網站
  2. PHP.ini 的上傳檔案限制
  3. httpd.conf 中文說明
  4. PHP 換頁 - 使用 Bootstrap 美化
  5. PHP上傳檔案 - 使用 Boostrap 美化
  6. PHP登入-使用 Bootstrap 美化
  7. Mysql 出現亂碼的處理方式


2012年5月3日 星期四

Xpath 語法 - 使用 HtmlAgilityPack 於 C#

XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言。

XPath基於XML的樹狀結構,提供在資料結構樹中找尋節點的能力。起初 XPath 的提出的初衷是將其作為一個通用的、介於XPointer與XSL間的語法模型。但是 XPath 很快的被開發者採用來當作小型查詢語言。

引用 & 參考:XPath 語言XPath AxesXML Path Language (XPath)

XPATH 基本語法

  • para selects the para element children of the context node

    para 選擇 para 子元素的本文節點


  • * selects all element children of the context node

    * 選擇所有子元素的本文節點


  • text() selects all text node children of the context node

    text() 選擇所有 text 子結點的本文節點


  • @name selects the name attribute of the context node

    @name 選擇所有 name 屬性的本文節點


  • @* selects all the attributes of the context node

    @* 選擇所有屬性的本文節點


  • para[1] selects the first para child of the context node

    para[1] 選擇所有第一個 para 元素的本文節點
  • para[last()] selects the last para child of the context node

    para[last()]選擇所最後一個 para 元素的本文節點


  • */para selects all para grandchildren of the context node

    */para 選擇所有 para 子孫的本文節點


  • /doc/chapter[5]/section[2] selects the second section of the fifth chapter of the doc

    /doc/chapter[5]/section[2] 選擇 doc 下的第五個 chapter 下的第二個 section 節點


  • chapter//para selects the para element descendants of the chapter element children of the context node

    chapter//para 選擇所有的父節點為chapter元素的para元素


  • //para selects all the para descendants of the document root and thus selects all para elements in the same document as the context node

    //para 選擇所有為 para 元素
  • //olist/item selects all the item elements in the same document as the context node that have an olist parent

    //olist/item 選擇所有父節點為 olist 元素的 item 元素


  • . selects the context node

    . 選擇當前節點


  • .//para selects the para element descendants of the context node

    .//para
  • 選擇當前節點的所有 para 子元素
  • .. selects the parent of the context node

    .. 選擇當前節點的父節點


  • ../@lang selects the lang attribute of the parent of the context node

    ../@lang 選擇名為 lang 的所有属性


  • para[@type="warning"] selects all para children of the context node that have a type attribute with value warning

    para[@type="warning"] 選擇所有 title 元素,且這些元素擁有值為 warning 的 lang 属性


  • para[@type="warning"][5] selects the fifth para child of the context node that has a type attribute with value warning

    para[@type="warning"][5] 選擇所有 title 元素,且這些元素擁有值為 warning 的 lang 属性的第五個節點


  • para[5][@type="warning"] selects the fifth para child of the context node if that child has a type attribute with value warning

    para[5][@type="warning"] 選擇所有 title 元素的第五個節點,且這個元素擁有值為 warning 的 lang 属性


  • chapter[title="Introduction"] selects the chapter children of the context node that have one or more title children with string-value equal to Introduction

    chapter[title="Introduction"] 選擇所有 chapter 元素,且其中的 title 元素的值等於 Introduction


  • chapter[title] selects the chapter children of the context node that have one or more title children

    chapter[title] 選擇所有 chapter 元素,且其中有 title 元素的值


  • employee[@secretary and @assistant] selects all the employee children of the context node that have both a secretary attribute and an assistant attribute


    employee[@secretary and @assistant] 選擇所有 employee 元素,且其中有 assistant 和 secretary 屬性的元素



XPATH 座標軸

  • ancestor 選擇當前節點的所有先輩(父、祖父等)
  • ancestor-or-self 選擇當前節点的所有先辈(父、祖父等)以及當前節點本身
  • attribute 選擇當前節點的所有屬性
  • child 選擇當前節點的所有子元素
  • descendant選擇當前節點的所有後代元素(子、孫等)
  • descendant-or-self 選擇當前節點的所有後代元素(子、孫等)以及當前節點本身
  • following 選擇文檔中當前節點的结束標籤之後的所有節點
  • namespace 選擇當前節點的所有命名空間節點
  • parent 選擇當前節點的父節點
  • preceding 選擇文檔中當前節點的開始標籤之前的所有節點
  • preceding-sibling 選擇當前節點之前的所有同级節點
  • self 選擇當前節點

使用範例

要擷取某些節點,必須要先觀察節點的獨特性質,或者是共通屬性,我通常都是使用 firefox 的外掛來觀察,IE 和 chrome 都有這種元件。
這次的例子我們在 google 上輸入 xpath,想要擷取前 10 筆網頁的標題,就先觀察它的網頁結構。

可以利用上面解說的方法,依照網頁結構來擷取,在程式中寫入以下 C# 程式碼:
HtmlWeb web;
HtmlDocument doc;
HtmlNodeCollection nodes;
string xp_title = string.Empty;


web = new HtmlWeb();
doc = web.Load("http://www.google.com/search?hl=en&q=xpath&oq=XPath");

xp_title = @"//h3[@class=""r""]";
nodes = doc.DocumentNode.SelectNodes(xp_title);

foreach (HtmlNode node in nodes)
{
    Console.WriteLine(node.InnerText);
}

執行結果如下:

比起 regular expression 輕鬆的是,它是以網頁結構去擷取,而 regular expression 是依照匹配字串做比對,所以在比對上 regular expression 比較有難度。
但是,在特殊情況下,還是需要利用 regular expression 做精密的解析。


回C#目錄
回首頁

2012年4月16日 星期一

jquery ui for bootstrap 的使用

最近常常使用 Bootstrap 在做版面配置,頓時覺得 UI 美化是一件很輕鬆的事情,只是要我設計出這種羽量級且各大瀏覽器都通用的 css,那叫我去撞牆會比較快。

可是在我網頁缺少日歷的元件時,才發現他少了這麼個東西,應該是說要用甚麼卻發現沒有才知道沒有,所以我就去 google 了一下,找到一個 Bootstrap 相容的外掛,居然還是 jquery ui,那我就毫不客氣的去引用啦!

果然好用,以下就介紹使用他流程:

1.

首先先到 jquery for bootstrap 下載檔案:

2.

解壓縮出來,將必要的檔案取出來並分類建立路徑 ( 暫以解壓縮出來的檔案路徑為路徑 )

需要的檔案:
  • css/custom-theme/jquery-ui-1.8.16.custom.css
  • bootstrap/bootstrap.css
  • js/jquery-1.6.2.min.js
  • js/jquery-ui-1.8.16.custom.min.js

3.

最後我建立一個 sample 檔案,供大家隨意取用:
<html>
    <head>
        <link type="text/css" rel="stylesheet"
href="css/custom-theme/jquery-ui-1.8.16.custom.css"/>
        <link href="bootstrap/bootstrap.css" rel="stylesheet">
    </head>
    
    <body>
        <div id="datepicker"></div>
    </body>
    
    <script type="text/javascript" 
src="js/jquery-1.6.2.min.js"></script>
    <script type="text/javascript" 
src="js/jquery-ui-1.8.16.custom.min.js"></script>
    
    <script>
        $('#datepicker').datepicker();
    </script>
</html>

回html目錄
回首頁

2012年4月11日 星期三

SQL 自製類別

這個 SQL 類別為我個人設計並撰寫,可能設計的不夠完整,就請廣大的觀眾多多指教囉!

若要引用請註明來源,歡迎取用。







使用範例:
private SQL sql;

protected void Page_Load(object sender, EventArgs e)
{
    sql = new SQL("NorthwindConnectionString", 
        SQLConnectionType.SettingsName);

    Hashtable ht = new Hashtable();
    ht.Add("eID", "1");

    gv.DataSource = sql.ExecuteDataTable(
        "SELECT * FROM Employees WHERE EmployeeID=@eID ", ht);
    gv.DataBind();
    

}

類別程式碼如下:
public enum SQLConnectionType
{
    ConnectionString,
    SettingsName
};

/// <summary>
/// SQL 的摘要描述
/// </summary>
public class SQL
{
    private DataTable dt;

    private SqlConnection connection;
    private SqlCommand command;
    private SqlDataAdapter adapter;
    public SqlDataReader reader { get; set; }
    private SqlTransaction tran;
    public bool isError { get; set; }
    public string errorMessage { get; set; }

    /// <summary>
    /// 
    /// </summary>
    public SQL()
    {

    }

    /// <summary>
    /// 初始化資料庫連線
    /// </summary>
    public SQL(string strConnection, SQLConnectionType type)
    {
        Connection(strConnection, type);
    }

    /// <summary>
    /// 資料庫連線
    /// </summary>
    /// <param name="strConnection">連接字串</param>
    /// <param name="type">資料庫連線方式</param>
    public void Connection(string strConnection, SQLConnectionType type)
    {
        connection = new SqlConnection();
        command = new SqlCommand();

        switch (type)
        {
            case SQLConnectionType.ConnectionString:
                
                connection.ConnectionString = strConnection;
                command.Connection = connection;
                
                break;

            case SQLConnectionType.SettingsName:

                connection.ConnectionString =
                    ConfigurationManager.ConnectionStrings[strConnection].
                    ConnectionString;
                command.Connection = connection;

                break;
        }
    }

    /// <summary>
    /// 執行資料庫語法
    /// </summary>
    /// <param name="query">指令</param>
    public void Execute(string query)
    {
        command.CommandText = query;
        connection.Open();

        isError = false;
        try
        {
            // 開始執行資料庫交易
            tran = connection.BeginTransaction();
            command.Transaction = tran;
            command.ExecuteNonQuery();
            tran.Commit();

        }
        catch (Exception ex)
        {
            // 失敗則 Rollback
            tran.Rollback();

            errorMessage = ex.Message;
            isError = true;
        }
        finally
        {
            connection.Close();
        }
    }

    /// <summary>
    /// 執行資料庫語法
    /// </summary>
    /// <param name="query">指令</param>
    /// <param name="ht">參數</param>
    public void Execute(string query, Hashtable ht)
    {
        SetParameters(ht);
        Execute(query);
    }

    /// <summary>
    /// 傳回結果第一行第一列之資料
    /// </summary>
    /// <param name="query">指令</param>
    /// <returns></returns>
    public object ExecuteScalar(string query)
    {
        object obj = string.Empty;

        command.CommandText = query;
        connection.Open();

        isError = false;
        try
        {
            obj = command.ExecuteScalar();
        }
        catch (Exception ex)
        {
            errorMessage = ex.Message;
            isError = true;
        }
        finally
        {
            connection.Close();
        }

        return obj;
    }

    /// <summary>
    /// 傳回結果第一行第一列之資料
    /// </summary>
    /// <param name="query">指令</param>
    /// <param name="ht">參數</param>
    /// <returns></returns>
    public object ExecuteScalar(string query, Hashtable ht)
    {
        SetParameters(ht);

        return ExecuteScalar(query);
    }


    /// <summary>
    /// 傳回 DataTable
    /// </summary>
    /// <param name="query">指令</param>
    /// <returns></returns>
    public DataTable ExecuteDataTable(string query)
    {
        dt = new DataTable();
        command.CommandText = query;
        
        isError = false;
        try
        {
            adapter = new SqlDataAdapter(command);
            adapter.Fill(dt);
        }
        catch(Exception ex)
        {
            errorMessage = ex.Message;
            isError = true;
        }

        return dt;
    }

    /// <summary>
    /// 傳回 DataTable
    /// </summary>
    /// <param name="query">指令</param>
    /// <param name="ht">參數</param>
    /// <returns></returns>
    public DataTable ExecuteDataTable(string query, Hashtable ht)
    {
        SetParameters(ht);

        return ExecuteDataTable(query);
    }

    /// <summary>
    /// 傳回 SqlDataReader
    /// </summary>
    /// <param name="query">指令</param>
    public SqlDataReader ExecuteReader(string query)
    {
        command.CommandText = query;

        reader = command.ExecuteReader();

        return reader;
    }

    /// <summary>
    /// 傳回 SqlDataReader
    /// </summary>
    /// <param name="query">指令</param>
    /// <param name="ht">參數</param>
    /// <returns></returns>
    public SqlDataReader ExecuteReader(string query, Hashtable ht)
    {
        SetParameters(ht);
        return ExecuteReader(query);
    }

    /// <summary>
    /// 查詢資料是否存在
    /// </summary>
    /// <param name="query">指令</param>
    /// <returns></returns>
    public bool Exists(string query)
    {
        object obj;
        bool isExists = false;
        int iResult = 0;

        command.CommandText = query;
        connection.Open();

        isError = false;
        try
        {
            obj = command.ExecuteScalar();

            if (int.TryParse(Convert.ToString(obj), out iResult))
            {
                if (iResult > 0)
                    isExists = true;
            }
        }
        catch (Exception ex)
        {
            errorMessage = ex.Message;
            isError = true;
        }
        finally
        {
            connection.Close();
        }

        return isExists;
    }

    /// <summary>
    /// 查詢資料是否存在
    /// </summary>
    /// <param name="query">指令</param>
    /// <param name="ht">參數</param>
    /// <returns></returns>
    public bool Exists(string query, Hashtable ht)
    {
        SetParameters(ht);
        return Exists(query);
    }

    /// <summary>
    /// 將資料庫連線開啟或關閉
    /// </summary>
    /// <param name="strStatus">狀態字串(open or close)</param>
    public void CallConnection(string strStatus)
    {
        switch (strStatus.ToLower())
        {
            case "open":
                if (connection.State == ConnectionState.Closed)
                    connection.Open();
                break;
            case "close":
                if (connection.State == ConnectionState.Open)
                    connection.Close();
                break;

        }
    }

    /// <summary>
    /// 設定參數
    /// </summary>
    /// <param name="ht">參數</param>
    private void SetParameters(Hashtable ht)
    {
        command.Parameters.Clear();
        foreach (DictionaryEntry de in ht)
            command.Parameters.AddWithValue(Convert.ToString(de.Key),
            Convert.ToString(de.Value));
    }
}

回C#目錄
回首頁

2012年4月10日 星期二

Bootstrap 於 Asp.net 的基本使用

Bootstrap 為一個 Open Source ( 開放程式碼 ) 的前台開發工具包,是一個簡單、靈活的 HTML、CSS、Javascript 的 UI 套件。
通常好的 UI 能讓瀏覽者多留 3 - 5 秒,當然,最重要的還是內容。但是可以因為這 3 - 5 秒讓瀏覽者注意到內容,那 UI 算是很重要的一塊。
Bootstrap 使得網頁開發者不需要再為 UI 介面設計所煩惱,它提供了整體化的設計和網頁控制項的美化,要單用或全用都很方便,引入 css 檔案或 js 檔案,在配合 css class 的使用,即可達到美化作用。

以下就介紹 Bootstrap 於 Asp.net 的使用流程:

1.

首先到 Bootstrap 下載檔案

2.

下載完解壓縮出來會有以下路徑資料夾

3.

在 css 下有兩個檔案,分別為 bootstrap.css 和 bootstrap.min.css

4.

將這兩個檔案複製下來,放入 Asp.net 專案內的 css 分類資料夾下

5.

接著在主板頁面 ( *.master ) 或者是網頁 ( *.aspx、*.html ) 中引用

6.

在頁面上可以先做個實驗,拉一個按鈕 ( Button ) 到頁面上

7.

回到 Bootstrap 的官方網頁,看看Bootstrap 按鈕如何使用

8.

最後我們可以套用 css,在 Asp.net 有 Intellisense ( 智能提示 ) 可以方便的套用,這個案例我們使用的類別是 btn btn-primary

9.

最後執行後就可以看到套用的是否成功,LOOK,是不是很舒服?


回aspnet目錄
回首頁

2012年4月9日 星期一

GridView 新增、刪除、修改以及排序

在 Asp.net 中 GridView 也可以做很多的事情,不只有顯示資料而已。

最近研究了在 GridView 中也能新增、刪除、修改以及排序,參考了兩篇文章

GridView 排序
GridView 新刪修

經過稍加修改後,使用微軟範例資料庫 NorthWind ( 北風 ) 做測試,終於完成,以下為 *.aspx 程式碼:
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false" 
    OnRowEditing="gv_RowEditing" OnRowCancelingEdit="gv_RowCancelingEdit"
    OnRowUpdating="gv_RowUpdating" BackColor="#DDDDDD" BorderStyle="None"
    BorderWidth="1px" CellPadding="5" CellSpacing="1" GridLines="None"
    Style="line-height: 22px; width: 100%;" onrowdeleting="gv_RowDeleting" 
    AllowPaging="True" onpageindexchanging="gv_PageIndexChanging" 
    PageSize="10" AllowSorting="True" onsorting="gv_Sorting">
    <RowStyle BackColor="#ffffff" ForeColor="Black" />
    <FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
    <PagerStyle BackColor="#ffffff" HorizontalAlign="left" />
    <HeaderStyle BackColor="#efefef" Font-Bold="True" />
    <AlternatingRowStyle BackColor="#f7fafe" />
    <EmptyDataTemplate>
        Sorry, No any data.
    </EmptyDataTemplate>
    <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:LinkButton ID="lbInsert" runat="server" Width="70px" 
                onclick="lbInsert_Click">新增</asp:LinkButton>
            </HeaderTemplate>
            <ItemTemplate>
                <asp:LinkButton ID="lbEdit" runat="server" 
                CommandName="Edit">編輯</asp:LinkButton> 
                |
                <asp:LinkButton ID="lbDelete" runat="server" 
                OnClientClick="javascript:return confirm('確定刪除?')" 
                CommandName="Delete">刪除</asp:LinkButton>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:LinkButton ID="lbUpdate" runat="server" 
                CommandName="Update">更新</asp:LinkButton>
                |
                <asp:LinkButton ID="lbCancelUpdate" runat="server" 
                CommandName="Cancel">取消</asp:LinkButton>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:LinkButton ID="lbSave" runat="server" 
                onclick="lbSave_Click">儲存</asp:LinkButton>
                |
                <asp:LinkButton ID="lbCancelSave" runat="server" 
                onclick="lbCancelSave_Click">取消</asp:LinkButton>
            
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="客戶編號" SortExpression="CustomerID">
            <ItemTemplate>
                <asp:Label ID="lblCustomerID" runat="server" 
                Text='<%# Eval("CustomerID") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:Label ID="lblCustomerIDEdit" runat="server" 
                Text='<%# Eval("CustomerID") %>'></asp:Label>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbCustomerIDFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="公司名稱" SortExpression="CompanyName">
            <ItemTemplate>
                <asp:Label ID="lblCompanyName" runat="server" 
                Text='<%# Eval("CompanyName") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbCompanyNameEdit" runat="server" 
                Text='<%# Eval("CompanyName") %>' ></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbCompanyNameFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="聯絡人姓名" SortExpression="ContactName">
            <ItemTemplate>
                <asp:Label ID="lblContactName" runat="server" 
                Text='<%# Eval("ContactName") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbContactNameEdit" runat="server" 
                Text='<%# Eval("ContactName") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbContactNameFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="聯絡人職稱" SortExpression="ContactTitle">
            <ItemTemplate>
                <asp:Label ID="lblContactTitle" runat="server" 
                Text='<%# Eval("ContactTitle") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbContactTitleEdit" runat="server" 
                Text='<%# Eval("ContactTitle") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbContactTitleFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="地址" SortExpression="Address">
            <ItemTemplate>
                <asp:Label ID="lblAddress" runat="server" 
                Text='<%# Eval("Address") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbAddressEdit" runat="server" 
                Text='<%# Eval("Address") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbAddressFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="城市" SortExpression="City">
            <ItemTemplate>
                <asp:Label ID="lblCity" runat="server" 
                Text='<%# Eval("City") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbCityEdit" runat="server" 
                Text='<%# Eval("City") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbCityFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="地區" SortExpression="Region">
            <ItemTemplate>
                <asp:Label ID="lblRegion" runat="server" 
                Text='<%# Eval("Region") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbRegionEdit" runat="server" 
                Text='<%# Eval("Region") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbRegionFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="郵遞區號" SortExpression="PostalCode">
            <ItemTemplate>
                <asp:Label ID="lblPostalCode" runat="server" 
                Text='<%# Eval("PostalCode") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbPostalCodeEdit" runat="server" 
                Text='<%# Eval("PostalCode") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbPostalCodeFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="國家" SortExpression="Country">
            <ItemTemplate>
                <asp:Label ID="lblCountry" runat="server" 
                Text='<%# Eval("Country") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbCountryEdit" runat="server" 
                Text='<%# Eval("Country") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbCountryFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="電話" SortExpression="Phone">
            <ItemTemplate>
                <asp:Label ID="lblPhone" runat="server" 
                Text='<%# Eval("Phone") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbPhoneEdit" runat="server" 
                Text='<%# Eval("Phone") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbPhoneFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="傳真" SortExpression="Fax">
            <ItemTemplate>
                <asp:Label ID="lblFax" runat="server" 
                Text='<%# Eval("Fax") %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="tbFaxEdit" runat="server" 
                Text='<%# Eval("Fax") %>'></asp:TextBox>
            </EditItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="tbFaxFooter" runat="server" 
                Text=""></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

而 *.cs 檔要引用三個參考,
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

程式碼:
private SqlConnection connection;
private SqlCommand command;
private SqlDataAdapter adapter;
private DataTable dt;

private string strConnection;
private string strConnectionName = "NorthwindConnectionString";

protected void Page_Load(object sender, EventArgs e)
{
    /* 建立資料庫連線 */
    strConnection = ConfigurationManager.
        ConnectionStrings[strConnectionName].ConnectionString;
    connection = new SqlConnection(strConnection);
    command = new SqlCommand();
    command.Connection = connection;

    if (!IsPostBack)
        GVGetData();
}

/// <summary>
/// 取得資料
/// </summary>
private DataTable GetData()
{
    dt = new DataTable();
    command.CommandText = "SELECT * FROM Customers ";
    adapter = new SqlDataAdapter(command);

    adapter.Fill(dt);

    return dt;
}

/// <summary>
/// 取得資料
/// </summary>
private void GVGetData()
{
    DataTable _dt;

    if (ViewState["se"] == null)
    {
        _dt = GetData();
        gv.DataSource = _dt;
        gv.DataBind();
    }
    else
    {
        string se = Convert.ToString(ViewState["se"]);
        SortDirection sd = (SortDirection)ViewState["sd"];
        this.GVGetData(sd, se);
    }
}

/// <summary>
/// 取得排序資料
/// </summary>
private void GVGetData(SortDirection pSortDirection, 
    string pSortExpression)
{
    DataTable _dt = GetData();

    string sSort = string.Empty;
    if (pSortDirection == SortDirection.Ascending)
    {
        sSort = pSortExpression;
    }
    else
    {
        sSort = string.Format("{0} {1}", pSortExpression, "DESC"); 
    }

    DataView dv = _dt.DefaultView;
    dv.Sort = sSort;

    gv.DataSource = dv;
    gv.DataBind();

}

/// <summary>
/// 編輯資料
/// </summary>
protected void gv_RowEditing(object sender, GridViewEditEventArgs e)
{
    gv.EditIndex = e.NewEditIndex;

    GVGetData();
}

/// <summary>
/// 取消編輯
/// </summary>
protected void gv_RowCancelingEdit(object sender, 
    GridViewCancelEditEventArgs e)
{
    gv.EditIndex = -1;

    GVGetData();
}

/// <summary>
/// 更新資料
/// </summary>
protected void gv_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    string strCustomerID, strCompanyName, strContactName, strContactTitle, strAddress, 
           strCity, strRegion, strPostalCode, strCountry, strPhone, strFax;

    strCustomerID = ((Label)gv.Rows[e.RowIndex].Cells[0].
        FindControl("lblCustomerIDEdit")).Text;
    strCompanyName = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbCompanyNameEdit")).Text;
    strContactName = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbContactNameEdit")).Text;
    strContactTitle = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbContactTitleEdit")).Text;
    strAddress = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbAddressEdit")).Text;
    strCity = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbCityEdit")).Text;
    strRegion = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbRegionEdit")).Text;
    strPostalCode = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbPostalCodeEdit")).Text; ;
    strCountry = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbCountryEdit")).Text;
    strPhone = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbPhoneEdit")).Text;
    strFax = ((TextBox)gv.Rows[e.RowIndex].Cells[0].
        FindControl("tbFaxEdit")).Text;

    /* 更新資料驗證作業 
       ...
       ...
       ...
    */

    /* 更新資料 */
    command.Parameters.Clear();
    command.Parameters.AddWithValue("customerID", strCustomerID);
    command.Parameters.AddWithValue("companyName", strCompanyName);
    command.Parameters.AddWithValue("contactName", strContactName);
    command.Parameters.AddWithValue("contactTitle", strContactTitle);
    command.Parameters.AddWithValue("address", strAddress);
    command.Parameters.AddWithValue("city", strCity);
    command.Parameters.AddWithValue("region", strRegion);
    command.Parameters.AddWithValue("postalCode", strPostalCode);
    command.Parameters.AddWithValue("country", strCountry);
    command.Parameters.AddWithValue("phone", strPhone);
    command.Parameters.AddWithValue("fax", strFax);

    command.CommandText = 
        @"UPDATE Customers SET CompanyName=@companyName, " +
        @"ContactName=@contactName, ContactTitle=@contactTitle, " +
        @"Address=@address, City=@city, Region=@region, " +
        @"PostalCode=@postalCode, Country=@country, " +
        @"Phone=@phone, Fax=@fax " +
        @"WHERE CustomerID=@customerID ";

    connection.Open();
    command.ExecuteNonQuery();
    connection.Close();

    gv.EditIndex = -1;

    GVGetData();
}

/// <summary>
/// 刪除資料
/// </summary>
protected void gv_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    string strCustomerID;

    strCustomerID = ((Label)gv.Rows[e.RowIndex].Cells[0].
        FindControl("lblCustomerID")).Text;

    /* 刪除資料 */
    command.Parameters.Clear();
    command.Parameters.AddWithValue("customerID", strCustomerID);

    command.CommandText = 
        "DELETE FROM Customers WHERE CustomerID=@customerID ";

    connection.Open();
    command.ExecuteNonQuery();
    connection.Close();

    GVGetData();
}

protected void lbInsert_Click(object sender, EventArgs e)
{
    gv.FooterRow.Visible = true;
}

protected void lbCancelSave_Click(object sender, EventArgs e)
{
    gv.FooterRow.Visible = false;
}

/// <summary>
/// 儲存資料
/// </summary>
protected void lbSave_Click(object sender, EventArgs e)
{
    string strCustomerID, strCompanyName, strContactName, strContactTitle, strAddress,
           strCity, strRegion, strPostalCode, strCountry, strPhone, strFax;

    strCustomerID = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbCustomerIDFooter")).Text;
    strCompanyName = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbCompanyNameFooter")).Text;
    strContactName = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbContactNameFooter")).Text;
    strContactTitle = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbContactTitleFooter")).Text;
    strAddress = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbAddressFooter")).Text;
    strCity = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbCityFooter")).Text;
    strRegion = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbRegionFooter")).Text;
    strPostalCode = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbPostalCodeFooter")).Text; ;
    strCountry = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbCountryFooter")).Text;
    strPhone = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbPhoneFooter")).Text;
    strFax = ((TextBox)gv.FooterRow.Cells[0].
        FindControl("tbFaxFooter")).Text;

    /* 新增資料驗證作業 
       ...
       ...
       ...
    */

    /* 更新資料 */
    command.Parameters.Clear();
    command.Parameters.AddWithValue("customerID", strCustomerID);
    command.Parameters.AddWithValue("companyName", strCompanyName);
    command.Parameters.AddWithValue("contactName", strContactName);
    command.Parameters.AddWithValue("contactTitle", strContactTitle);
    command.Parameters.AddWithValue("address", strAddress);
    command.Parameters.AddWithValue("city", strCity);
    command.Parameters.AddWithValue("region", strRegion);
    command.Parameters.AddWithValue("postalCode", strPostalCode);
    command.Parameters.AddWithValue("country", strCountry);
    command.Parameters.AddWithValue("phone", strPhone);
    command.Parameters.AddWithValue("fax", strFax);

    command.CommandText = 
        @"INSERT INTO Customers (CustomerID, CompanyName, " + 
        @"ContactName, ContactTitle, Address, City, Region, " +
        @"PostalCode, Country, Phone, Fax) VALUES (@customerID, " +
        @"@companyName, @contactName, @contactTitle, @address, " +
        @"@city, @region, @postalCode, @country, @phone, @fax )";

    connection.Open();
    command.ExecuteNonQuery();
    connection.Close();

    GVGetData();
}

/// <summary>
/// 換頁
/// </summary>
protected void gv_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gv.PageIndex = e.NewPageIndex;
    GVGetData();
}

/// <summary>
/// 排序
/// </summary>
protected void gv_Sorting(object sender, GridViewSortEventArgs e)
{
    string se = ViewState["se"] != null ? 
        Convert.ToString(ViewState["se"]) : string.Empty;
    SortDirection sd = ViewState["sd"] != null ? 
        (SortDirection)ViewState["sd"] : SortDirection.Ascending;

    if (string.IsNullOrEmpty(se))
    {
        se = e.SortExpression;
        sd = SortDirection.Ascending;
    }

    // 如果欄位與本來不同
    if (se != e.SortExpression)
    {
        // 切換為目前所指定欄位
        se = e.SortExpression;

        // 指定排列方式為升冪
        sd = SortDirection.Ascending;
    }
    // 如果欄位與本來相同
    else
    {
        // 切換升冪為降冪,降冪為升冪
        if (sd == SortDirection.Ascending)
            sd = SortDirection.Descending;
        else
            sd = SortDirection.Ascending;
    }

    // 紀錄欄位與排列方式 ( 升冪或降冪 )
    ViewState["se"] = se;
    ViewState["sd"] = sd;

    GVGetData(sd, se);
}

顯示:
新增:
刪除:
修改:
排序:

回aspnet目錄
回首頁