in

SDT Community Server

SDT Forums, Blogs, Photos server.

wego

  • 写个 C# string 转换类型扩展方法

    public static class StringExtension
    {
        public static T ChangeStringToType<T>(this string value)
        {
            if (typeof(T).IsValueType)
            {
                if (!typeof(T).IsEnum)
                {
                    return (T)Convert.ChangeType(value, typeof(T));
                }
                else
                {
                    return (T)Enum.Parse(typeof(T), value);
                }
            }
            else
            {
                if (typeof(T).IsArray)
                {
                    string[] strs = value.Split(new char[] { '\0' });
                    Type elementType = typeof(T).GetElementType();
                    Array array = Array.CreateInstance(elementType, strs.Length);
                    for (int i = 0; i < strs.Length; i++)
                    {
                        array.SetValue(TypeDescriptor.GetConverter(elementType).ConvertFrom(null, null, strs[i]), i);
                    }
                    return (T)Convert.ChangeType(array, typeof(T));
                }
                else
                {
                    throw new InvalidOperationException("Invalid cast from 'System.String' to '" + typeof(T).ToString() + "'.");
                }
            }
        }
    }

     

    public enum Role
    {
        Guest,
        Member,
        Manager,
        Admin

     

    // 调用:

    string a = "1";
    int b = a.ChangeStringToType<int>();  // 也可: var b = a.ChangeStringToType<int>();

     

    string c = "12-18-2009";  // 也可:  string c = "2009-12-18";
    DateTime d = c.ChangeStringToType<DateTime>();

     

    string e = "Member";
    Role f = e.ChangeStringToType<Role>();

     

    string g = "as\0sdk";
    string[] h = g.ChangeStringToType<string[]>();

     

    string i = "Guest\0Manager\0Admin";
    Role[] j = i.ChangeStringToType<Role[]>();

     

    // 上面的也可以直接使用字符串常量, 如:  DateTime d = "12-18-2009".ChangeStringToType<DateTime>();

     

    // 当然! 也可以发挥自己的创意, 定制一套规则协议, 使之能转换成 DataTable 等类型.

  • 使用 jQuery 处理 SimpleGridView 的一个选择行背景色问题

    使用 SimpleGridView 时, 如果需要在某些行添加特定背景样式, 则会出现点击这些行时,  它的背景色没有变成点击获焦行的背景色. 此时, 可使用如下 jQuery 脚本解决. 另外,  jQuery 非常好用, 方便灵活, 脚本代码大量减少, 网页大小也随之而小; 且良好的兼容性, 不用担心到了别的浏览器或其它版本效果就不一样. 所以非常推荐推荐!

     

    public void gvData_RowDataBound(object sender, GridViewRowEventArgs e)
    {
            switch (e.Row.RowType)
            {
                case DataControlRowType.DataRow:
                    if (...)
                    {
                        for (int i = 0; i < e.Row.Cells.Count - 1; i++)
                        {
                            e.Row.Cells[i].Attributes.Add("style", "font-weight:bold;background-color:#CCFFCC;");
                        }
                    }
                    break;
            }
    }

     

     

    protected void Page_Load(object sender, EventArgs e)
    {

                StringBuilder script = new StringBuilder();

     

                // global variable
                script.Append("var lastSelRow;");
                script.Append("var lastSelRowBgColor;");

     

                // reconvert backgroundColor for last selected row

                // :gt(index) :  匹配所有大于给定索引值的元素;  因为这里第1个 tr 是列标题行
                script.Append("$('#{0} tr:gt(0)').mousedown(function() {{ " +

     

                                    "if (lastSelRow) {{ " +
                                        "$(lastSelRow).children('td').each(function() {{ " +
                                            "$(this).css('backgroundColor', lastSelRowBgColor);" +
                                        "}}); " +
                                    "}} " +

     

                                    "lastSelRow = $(this)[0]; " +
                                    "lastSelRowBgColor = $(this).children('td:first').css('backgroundColor'); " +    
                         
                                "}});");

     

                // set backgroundColor for current selected row
                script.Append("$('#{0} tr:gt(0)').click(function() {{ " +                                      
                                    "$(this).children('td').each(function() {{ " +
                                        "$(this).css('backgroundColor', '#e1edf8'); " +
                                    "}}); " +
                                "}});");

                //
                ClientScript.RegisterStartupScript(this.GetType(), "SetSelRowBackgroundColor", string.Format(script.ToString(), gvData.ClientID), true);

    }

  • Oracle 竖变横需注意 ROWNUM & Order By

    WITH t AS
         (
            SELECT 'BU0301' bu
              FROM DUAL
            UNION ALL
            SELECT 'BU0701'
              FROM DUAL
            UNION ALL
            SELECT 'BU0401'
              FROM DUAL
            UNION ALL
            SELECT 'BU0501'
              FROM DUAL
            UNION ALL
            SELECT 'BU0401'
              FROM DUAL
            UNION ALL
            SELECT 'BU0801'
              FROM DUAL
            UNION ALL
            SELECT 'BU0901'
              FROM DUAL
            UNION ALL
            SELECT 'BU0201'
              FROM DUAL
            UNION ALL
            SELECT 'BU0101'
              FROM DUAL
            UNION ALL
            SELECT 'BU0601'
              FROM DUAL)


    SELECT     SUBSTR (MAX (SYS_CONNECT_BY_PATH ('''' || bu || '''', ', ')), 3)
          FROM (SELECT ROWNUM rn, bu
                  FROM (SELECT DISTINCT bu
                                   FROM t))
    START WITH rn = 1
    CONNECT BY rn - 1 = PRIOR rn; 

     

    -- 输出: 'BU0301', 'BU0201', 'BU0301', 'BU0401', 'BU0501', 'BU0601', 'BU0701', 'BU0801', 'BU0901'

    甚奇! 'BU0101' 不见了! 另外, 明明没 BU 重复且已加 DISTINCT, 但结果竟有 'BU0301' 重复!

     

     

    SELECT     SUBSTR (MAX (SYS_CONNECT_BY_PATH ('''' || bu || '''', ', ')), 3)
          FROM (SELECT ROWNUM rn, bu
                  FROM (SELECT DISTINCT bu
                                   FROM t
                               ORDER BY bu))
    START WITH rn = 1
    CONNECT BY rn - 1 = PRIOR rn;

     

    或者:

     

    SELECT     SUBSTR (MAX (SYS_CONNECT_BY_PATH ('''' || bu || '''', ', ')), 3)
          FROM (SELECT DISTINCT DENSE_RANK () OVER (ORDER BY bu) AS rn, bu
                           FROM t)
    START WITH rn = 1
    CONNECT BY rn - 1 = PRIOR rn;

     

    -- 输出: 'BU0101', 'BU0201', 'BU0301', 'BU0401', 'BU0501', 'BU0601', 'BU0701', 'BU0801', 'BU0901'

  • 当心在多线程中使用循环传递 HttpContext 参数

     今天发现在多线程中使用循环传递 HttpContext 参数时, 有时会出现传递失效的情况.  请见如下 Code

     

    delegate DataTable GetSegDataDelegate(HttpContext context, int reportid);
    DataTable dtSeg1, dtSeg2, dtSeg3;   

     

    protected void Page_Load(object sender, EventArgs e)
    {
        Session["company"] = "SHK";
        Session["currency"] = "USD";

        GetSegDataDelegate getSegDataDelegate = new GetSegDataDelegate(GetSegData);       

        for (int i = 7; i <= 9; i++)          // CodeA
        {           
            getSegDataDelegate.BeginInvoke(HttpContext.Current, i, new AsyncCallback(SetSegData), null);
        }

        while (dtSeg1 == null)
        { }
        gvData1.DataSource = dtSeg1;
        gvData1.DataBind();


        while (dtSeg2 == null)
        { }
        gvData2.DataSource = dtSeg2;
        gvData2.DataBind();


        while (dtSeg3 == null)
        { }
        gvData3.DataSource = dtSeg3;
        gvData3.DataBind();
    }

     

    public DataTable GetSegData(HttpContext context, int reportid)
    {
        DataTable dt = new DataTable();

        try
        {
            int i = 0;
            OracleParameter[] p = new OracleParameter[4];
            p[i] = new OracleParameter("p_cursor", OracleType.Cursor);
            p[i].Direction = ParameterDirection.Output;
            i++;
            p[i] = new OracleParameter("p_reportid", OracleType.Number);
            p[i].Value = reportid;
            i++;
            p[i] = new OracleParameter("p_company", OracleType.VarChar, 100);
            p[i].Value = context.Session["company"];                // CodeB
            i++;           
            p[i] = new OracleParameter("p_curr", OracleType.VarChar, 50);
            p[i].Value = context.Session["currency"];                 // CodeC
            i++;

            dt = db.ExecProcedure("ACCP.ACC_SEG_PKG.query_amount", p);
        }
        catch (Exception ex)
        {
            throw ex;
        }

        dt.TableName = "SEG" + reportid;
        return dt;
    }

     

    public void SetSegData(IAsyncResult result)
    {
        AsyncResult async = (AsyncResult)result;
        GetSegDataDelegate DelegateInstance = (GetSegDataDelegate)async.AsyncDelegate;
        DataTable dt = DelegateInstance.EndInvoke(result);
        switch (dt.TableName)
        {
            case "SEG7":
                dtSeg1 = dt;               
                break;

            case "SEG8":
                dtSeg2 = dt;               
                break;

            case "SEG9":
                dtSeg3 = dt;               
                break;
        }
    }
     

     

     当 CodeA 循环到第2或第3次时 (即 i=8 或 i=9 ), CodeB, CodeC 处找不到 Session 值(即 context.Session["company"] 和 context.Session["currency"] 为 null ), 表明传入的  HttpContext 参数失效. 但第1次 (即 i=7) 是完全没有问题的. 非常奇怪?!  可改成如下 code 处理之.

     

    delegate DataTable GetSegDataDelegate(string company, string currency, int reportid);
    DataTable dtSeg1, dtSeg2, dtSeg3;   

     

    protected void Page_Load(object sender, EventArgs e)
    {
        Session["company"] = "SHK";
        Session["currency"] = "HKD";

        GetSegDataDelegate getSegDataDelegate = new GetSegDataDelegate(GetSegData);       

        for (int i = 7; i <= 9; i++)
        {
            getSegDataDelegate.BeginInvoke(Session["company"].ToString(), Session["currency"].ToString(), i, new AsyncCallback(SetSegData), null);
        }

        while (dtSeg1 == null)
        { }
        gvData1.DataSource = dtSeg1;
        gvData1.DataBind();


        while (dtSeg2 == null)
        { }
        gvData2.DataSource = dtSeg2;
        gvData2.DataBind();


        while (dtSeg3 == null)
        { }
        gvData3.DataSource = dtSeg3;
        gvData3.DataBind();
    }

     

    public DataTable GetSegData(string company, string currency, int reportid)
    {
        DataTable dt = new DataTable();

        try
        {
            int i = 0;
            OracleParameter[] p = new OracleParameter[4];
            p[i] = new OracleParameter("p_cursor", OracleType.Cursor);
            p[i].Direction = ParameterDirection.Output;
            i++;
            p[i] = new OracleParameter("p_reportid", OracleType.Number);
            p[i].Value = reportid;
            i++;
            p[i] = new OracleParameter("p_company", OracleType.VarChar, 100);
            p[i].Value = company;
            i++;           
            p[i] = new OracleParameter("p_curr", OracleType.VarChar, 50);
            p[i].Value = currency;
            i++;

            dt = db.ExecProcedure("ACCP.ACC_SEG_PKG1.query_amount", p);
        }
        catch (Exception ex)
        {
            throw ex;
        }

        dt.TableName = "SEG" + reportid;
        return dt;

    }

     

    这里之所以采用多线程, 是为了提高查询速度. 之前运行的情况是 Procedure2 要等待 Procedure1 完成才运行,  Procedure3 要等待 Procedure2 完成才运行. 而现在是3个 Procedure 并列同步运行, 实际运行速度几乎是原来的3倍.

    另外还有一个注意点, 在线程回调过程里不可操作页面上的控件, 如下

     

    public void SetSegData(IAsyncResult result)
    {
        AsyncResult async = (AsyncResult)result;
        GetSegDataDelegate DelegateInstance = (GetSegDataDelegate)async.AsyncDelegate;
        DataTable dt = DelegateInstance.EndInvoke(result);
        switch (dt.TableName)
        {
            case "SEG7":               
                gvData1.DataSource = dt;
                gvData1.DataBind();
                break;

            case "SEG8":              
                gvData2.DataSource = dt;
                gvData2.DataBind();
                break;

            case "SEG9":            
                gvData3.DataSource = dt;
                gvData3.DataBind();
                break;
        }
    }

  • C# Class 访问用户控件 (ascx) 的属性

    C# Class (如在 /App_Code/BasePage.cs 中) 不能像页面文件那样使用如下方式访问用户控件 

     

    test.aspx 

    <%@ Reference Control="~/_SYS/Control/SearchTextBox/SearchTextBox.ascx" %>

     

     

    test.aspx.cs
    protected override void OnLoad(EventArgs e)
    {
              base.OnLoad(e);

     

              _SYS_Control_SearchTextBox_SearchTextBox c = FindControlEx(this, "SearchTextBox1") as _SYS_Control_SearchTextBox_SearchTextBox;

              if (c != null)
              {
                     c.TestProperty = "…";
              }
    }


    但可借助 Control > ClassName 属性解决. 但是有一缺点, 如下面例子, 若 TestUserControl.ascx 中的 TextBox1 控件 ID 后来改变了, 则 App_Code\TestUserControl.cs 中的相应代码也要作改动.

     

    App_Code\CommonFunc.cs

    public class CommonFunc
    {
        public static Control FindControlEx(Control parent, string id)
        {
            foreach (Control control in parent.Controls)
            {
                if (control.ID != null && control.ID.Equals(id))
                {
                    return control;
                }
                else
                {
                    if (control.HasControls())
                    {
                        Control subControl = FindControlEx(control, id);
                        if (subControl != null)
                        {
                            return subControl;
                        }
                    }
                }
            }
            return null;
        }

    }

     

    App_Code\TestUserControl.cs 

    public class TestUserControl : UserControl
    {   
        protected TextBox TextBox1
        {
            get
            {
                return CommonFunc.FindControlEx(this, "TextBox1") as TextBox;
            }
        }

        public string TestProperty
        {
            get
            {
                return TextBox1.Text;
            }
            set
            {
                TextBox1.Text = value;
            }
        }
    }

     

     TestUserControl.ascx

    <%@ Control Language="C#" ClassName="TestUserControl"  Inherits="TestUserControl" %>
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

     

    App_Code\BasePage.cs  

    public class BasePage : System.Web.UI.Page
    {
             protected override void OnLoad(EventArgs e)
             {
                     base.OnLoad(e);   


                     TestUserControl c = CommonFunc.FindControlEx(this, "TestUserControl1") as TestUserControl;          
                     if (c != null)          
                     {
                            c.TestProperty = "…";           
                     } 
             }

    }

  • ORACLE 自定义异常和输出错误信息及行号

    PROCEDURE p_test
    IS
       my_exception   EXCEPTION;
    BEGIN

       ...
       IF ...
       THEN
          RAISE my_exception;
       END IF;

        ... 


    EXCEPTION
       WHEN my_exception

       THEN
          DBMS_OUTPUT.put_line ('...');
       WHEN OTHERS
       THEN
          DBMS_OUTPUT.put_line ('Message: ' || SQLERRM);
          DBMS_OUTPUT.put_line ('Line No.: '
                                || DBMS_UTILITY.format_error_backtrace
                               );
    END;

  • Oracle 使用'名称定位参数' 调用 Function 或 Procedure

    Oracle 支持使用'名称定位参数' 调用 FUNCTION 或 PROCEDURE, 但有2个注意点. 请看如下 code

     

    FUNCTION F_TEST (p1 IN NUMBER, p2 IN VARCHAR2 := NULL, p3 IN VARCHAR2 := NULL)
       RETURN VARCHAR2
    IS
    BEGIN
       RETURN 'P3:' || p3;
    END;

     

    PROCEDURE P_TEST
    IS
       v_result   VARCHAR2 (100);
    BEGIN
       v_result := f_test (6, p3 => 'test');            --- A

       v_result := f_test (p3 => 'test', p1 => 6);   --- B

       SELECT f_test (6, p3 => 'test')                --- C
         INTO v_result
         FROM DUAL;

       v_result := f_test (p3 => 'test', 6);             ---D

       DBMS_OUTPUT.put_line (v_result);
    END;

     

    A), B) 正常运行

    C) 编译报错: PL/SQL: ORA-00907: 缺失右括号

        注意点1: 不能用在 sql 语句中

    D) 编译报错: PLS-00312: 一个定位相关参数没有说明其相关性

        注意点2: 所有位置参数须写在定位参数前面

     

    C# 4.0 也开始支持类似的 '名称定位参数' 使用了, 不知到时会否也有上面的点2需注意 Smile

     

       

     

  • IE8 VS2005 调试问题

    昨天安装 IE8 后发现 VS2005 的程序按 F5 运行后会进行非调试状态, 所有断点不会触发.后查阅网上资料可按如下方法解决.

    1. 点运行regedit.
    2. 定位到HKEY_LOCALMACHINE -> SOFTWARE -> Microsoft -> Internet Explorer -> Main
    3. 新建一名为TabProcGrowth的dword值, value 为0.

     

  • Oracle sys_refcursor 游标变量不能用作参数传递

    今天在使用 Oracle sys_refcursor 游标变量时, 抛出错误: 'Execution failed: ORA-00604: 递归 SQL 级别1出现错误', 'ORA-01001: 无效的游标'.  原来是sys_refcursor 游标变量不能用作参数传递.  请见如下 code:

      PROCEDURE P1(
          p_cursor     OUT    sys_refcursor,
          p_year        IN       NUMBER
       )

       BEGIN

           ......

           P2(p_cursor, 'test');

       END;

       PROCEDURE P2(
          p_cursor      OUT    sys_refcursor,
          p_company  IN       VARCHAR2
        )

        BEGIN

           ......

        END;

     

    需改成

     TYPE t_cursor IS REF CURSOR;   -- 在 PACKAGE(Spec) 中定义

      PROCEDURE P1(
          p_cursor     OUT    t_cursor,
          p_year        IN       NUMBER
       )

       BEGIN

           ......

           P2(p_cursor, 'test');

       END;

       PROCEDURE P2(
          p_cursor      OUT    t_cursor,
          p_company  IN       VARCHAR2
        )

        BEGIN

           ......

        END;

     

     

  • C# 泛型方法中的 out 参数问题

    C#  方法中的 out 参数中需要在方法内为其赋值, 而当 out 参数定义为泛型数据类型时, 因为其类型需运行时才具体确定, 有时要用到 C# 的一个特殊关键字 default.

     public class CacheHandler
    {
        public enum Keys
        {
            ReportLinks
        }

        protected static Cache CurrentCache
        {
            get { return HttpContext.Current.Cache; }
        }

        public static bool IsNull(Keys key)
        {
            return CurrentCache[key.ToString()] == null;
        }

        public static void Insert<T>(Keys key, T value)
        {
            CurrentCache.Insert(key.ToString(), value);
        }

        public static bool TryGetValue<T>(Keys key, out T value)
        {
            if (IsNull(key))
            {
                value = default(T);    // 这里不能写成 value = null;
                return false;
            }
            else
            {
                try
                {
                    value = (T)CurrentCache[key.ToString()];
                    return true;
                }
                catch (Exception ex)
                {
                    value = default(T);
                    return false;
                }
            }
        }
    }

    // 调用

    Dictionary<int, string> reportLinks;
    if (!CacheHandler.TryGetValue(CacheHandler.Keys.ReportLinks, out reportLinks))
    {
        reportLinks.Add(1, "test");
        // ...
        CacheHandler.Insert(CacheHandler.Keys.ReportLinks, reportLinks);
    }

  • 怪事年年有, 今年特别多之 Oracle ROLLUP

    Oracle 的 GROUP BY ROLLUP 具有分组合计功能, 非常好用! 以前一直用开都没什么问题. 但今天使用时发现一个奇怪现象, 同一条 sql 在数据库中(如在 SQL Navigator 工具) 正常运行, 但在 C# 中执行则抛出 'OCI-22060: argument [2] is an invalid or uninitialized number' 错误 (注意这个错误不是以 ORA 开头), 更奇怪的是我自己创建一个测试表,  改了一下 sql 表名则 C#  就执行正常了.  虽然很明显是数据问题, 但我查过多次数据也没什么特别.

    sql 缩简 如下:

    sqlA = "SELECT   companyid, SUM (f1) f1 " +
                       "FROM acc_a15_data a " +
                   "GROUP BY ROLLUP (companyid) ";

    sqlB = "SELECT   companyid, SUM (f1) f1 " +
                   "FROM  wego_test " +
               "GROUP BY ROLLUP (companyid) ";

    DataTable dtB = BESDb.Db.ExecQuery(sqlB);  -- 正常
     

    DataTable dtA = BESDb.Db.ExecQuery(sqlA);  -- 报错

     

    解决方法可改成如下:

    sqlA = "SELECT   TO_CHAR(companyid), SUM (f1) f1 " +
                       "FROM acc_a15_data a " +
                   "GROUP BY ROLLUP (companyid) ";

     

  • 使用数据库储存的文件内容作邮件附件

    请见如下 Code:

    string sql = string.Format("SELECT file_name, file_content FROM {0} WHERE id = {1}", DbTabeName, RecordID);
    string attachmentPath = null;

    DbDataReader reader = null;
    try
    {
        reader = BESDb.ExecReader(sql);
        reader.Read();

        attachmentPath = String.Format("{0}\\{1}", SessionInfo.TempDir, reader["file_name"].ToString());
        using (FileStream fs = new FileStream(attachmentPath, FileMode.Create, FileAccess.Write, FileShare.Write))
        {                  
            using (StreamWriter streamwriter = new StreamWriter(fs, Response.ContentEncoding))
            {
                byte[] fileContent = (byte[])reader["file_content"];
                streamwriter.BaseStream.Write(fileContent, 0, fileContent.Length);                      
            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        if (!reader.IsClosed)
        {
            reader.Close();
        }
    }

    simpleMail.Send(address, null, subject, body.ToString(), null, new string[] { attachmentPath });

     

  • ORACLE正则表达式 - 字符簇方括号匹配问题

    Oracle 正则中的字符簇在方括号匹配上有别于其它普通字符,  需改用 '|'  匹配符或如 '[[:digit:]pw]+' 的方式, 请见如下4项表达式.

    a. SELECT 1 FROM DUAL WHERE REGEXP_LIKE ('wap', '[pwa]+')  -- 1

    b. SELECT 1 FROM DUAL WHERE REGEXP_LIKE ('w2p', '[pw[[:digit:]]]+')  -- null

    c. SELECT 1 FROM DUAL WHERE REGEXP_LIKE ('w2p', '(pw|[[:digit:]])+')  -- 1

    d. SELECT 1 FROM DUAL WHERE REGEXP_LIKE ('w2p', '[[:digit:]pw]+')  -- 1

    Posted Apr 08 2009, 01:51 PM by wego with no comments
    Filed under:
  • UpdatePanel 转用 span 作容器及网页源码的截获和加工

    UpdatePanel 自身使用 div 作为容器, 有时产生的问题是出现不希望的换行 (例如: 希望 UpdatePanel 外两边的控件和其内部的控件位于同一行), 可考虑使用如下方式解决之 (思路: 截获网页客户端源码, 将其有关的 div 转成 span)

    public class UpdatePanel : System.Web.UI.UpdatePanel
    {
        public bool UseSpanAsContainer { get; set; }           

        protected override void Render(HtmlTextWriter writer)
        {
            if (UseSpanAsContainer && !IsInPartialRendering)
            {
                Page.Response.Filter = new HttpResponseFilter(Page.Response.Filter);

                HttpResponseFilter filter = (HttpResponseFilter)Page.Response.Filter;
                filter.OnSourceCodeWrited += sourceCode =>
                {
                    string destinationCode = sourceCode;

                    string pattern = "<" + ClientID + ">\\s*<div";
                    destinationCode = Regex.Replace(destinationCode, pattern, "<span");

                    pattern = "</div>\\s*</" + ClientID + ">";
                    destinationCode = Regex.Replace(destinationCode, pattern, "</span>");

                    return destinationCode;
                };          

                //
                writer.RenderBeginTag(ClientID);
                base.Render(writer);
                writer.RenderEndTag();
            }
            else
            {
                base.Render(writer);
            }
        }
    }   

    public class HttpResponseFilter : Stream
    {
        Stream responseStream;   
        StringBuilder responseHtml;

        public delegate string SourceCodeWrited_EventHandler(string sourceCode);
        public event SourceCodeWrited_EventHandler OnSourceCodeWrited;

        public HttpResponseFilter(Stream inputStream)
        {
            responseStream = inputStream;
            responseHtml = new StringBuilder();
        }

        public override bool CanRead
        {
            get
            {
                return true;
            }
        }

        public override bool CanSeek
        {
            get
            {
                return true;
            }
        }

        public override bool CanWrite
        {
            get
            {
                return true;
            }
        }

        public override void Close()
        {
            responseStream.Close();
        }

        public override void Flush()
        {
            responseStream.Flush();
        }

        public override long Length
        {
            get
            {
                return 0;
            }
        }

        public override long Position { get; set; }   

        public override int Read(byte[] buffer, int offset, int count)
        {
            return responseStream.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return responseStream.Seek(offset, origin);
        }

        public override void SetLength(long length)
        {
            responseStream.SetLength(length);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

            Regex eof = new Regex("</html>", RegexOptions.IgnoreCase);

            if (!eof.IsMatch(strBuffer))
            {
                responseHtml.Append(strBuffer);
            }
            else
            {
                responseHtml.Append(strBuffer);
                string finalHtml = responseHtml.ToString();


                 /*  这里比较奇怪, 第一次截获会输出如 "<html><head><title>Object moved</title></head><body>
    <h2>Object moved to <a href="%2fITMC%2fHardware%2fAccount%2fComputer.aspx%3f_slbg%3d0%26_slbi%3d0" mce_href="%2fITMC%2fHardware%2fAccount%2fComputer.aspx%3f_slbg%3d0%26_slbi%3d0">here</a>.</h2>
    </body></html>" 的源码, 所以需过滤掉 (这里说的 "第一次" 不是 Page.IsPostBack, 而是系统关闭后再重新运行 ) */

                if (!finalHtml.StartsWith("<html><head><title>Object moved</title>"))
                {
                    OnSourceCodeWrited.DoIfNotNull((obj) => finalHtml = OnSourceCodeWrited(finalHtml));
                }

                byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
                responseStream.Write(data, 0, data.Length);
            }
        }
    }

    令外, 由于UpdatePanel 是位于 System.Web.UI 命名空间而非 System.Web.UI.WebControls, 所以不能像 WebControls 一样直接如下解决:

    protected override HtmlTextWriterTag TagKey
    {

        get { return HtmlTextWriterTag.Span; }
    }    

     

  • 结合 UpdatePanel DropDownList 使用的一个 bug

     

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <itmc:Localize runat="server" ID="Localize1" Text="<%$ Resources:Labels,Module %>" />
            <itmc:DropDownList runat="server" ID="ddlNavModule" AutoPostBack="true" OnSelectedIndexChanged="ddlNavModule_SelectedIndexChanged">
            </itmc:DropDownList>
            &nbsp;
            <itmc:Localize runat="server" ID="Localize2" Text="<%$ Resources:Labels,FunctionGroup %>" />
            <itmc:DropDownList runat="server" ID="ddlNavGroup" AutoPostBack="true" OnSelectedIndexChanged="ddlNavGroup_SelectedIndexChanged">
            </itmc:DropDownList>
            &nbsp;
            <itmc:Localize runat="server" ID="Localize4" Text="<%$ Resources:Labels,Function %>" />
            <itmc:DropDownList runat="server" ID="ddlNavMember">
            </itmc:DropDownList>
        </ContentTemplate>
    </asp:UpdatePanel>

    public class DropDownList : SimpleDropDownList

    {

            ...

            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);

                ...

                //
                if (ItemUseResource == true)
                {
                    foreach (ListItem item in Items)
                    {
                        if (!SpecialItems.Contains(item.Value))
                        {
                            string itemValue = item.Value;      // 语句 a
                            item.Text = GlobalResource.GetLabString(item.Text);
                            item.Value = itemValue;              // 语句 b
                        }
                    }
                }
            }

    }

    如果页面使用了 UpdatePanel  且 OnPreRender 发生在异步刷新过程中, 必须添加语句a和b, 否则 item.Value 自动等于 item.Text

  • window.onunload 在 IE6, 7 上的差异

    // javascript 

    window.onunload = function() {

        alert('b');

    }

     

    // C#

    protected void Page_Load(object sender, EventArgs e)
    {

        Page.ClientScript.RegisterStartupScript(Page.GetType(), "test", "alert('a'); window.returnValue = '1'; window.close();", true);

    }

     

    //

    假设页面为模式弹出窗体, IE6 不会执行 window.onunload , 即只弹出 "a"; 而 IE7 会执行 window.onunload, 即弹出 "a" 和 "b".

    故在模式窗体最好尽量少用  window.onunload, 因为您系统中用 IE6 或 7 的用户可能都有.

     

     

  • throw 语句在委托中需加花括号

    public static class ObjectExtension
    {

        public static void DoIfNull(this object data, Action action)
            {
                if (data == null)
                {
                    action();
                }
            }
    }

    DataRow dr = ...

    int i =1;

    dr.DoIfNull(() =>  throw new ApplicationException(GlobalResource.GetMsgString("EmailNotExists")) );   // 不能编译通过

    dr.DoIfNull(() =>  i = 100 );   // 可以编译通过, 同样是单条语句

    dr.DoIfNull(() => { throw new ApplicationException(GlobalResource.GetMsgString("EmailNotExists")); });  // 可以编译通过

     

  • Oracle复合数据结构的一个注意点

    CREATE OR REPLACE TYPE t_str_array AS TABLE OF VARCHAR2 (500); 

     

     SELECT b.COLUMN_VALUE  FROM bd_pc_type a, TABLE (t_str_array ('手提', '工作站', '手提机')) b

     WHERE a.code(+) = b.COLUMN_VALUE AND a.code IS NULL

     

    无记录返回, 若改成

     

      SELECT a.code, b.COLUMN_VALUE  FROM bd_pc_type a, TABLE (t_str_array ('手提', '工作站', '手提机')) b

     WHERE a.code(+) = b.COLUMN_VALUE AND a.code IS NULL

     

    有记录返回

  • LINQ 无短路

    昨天在用 LINQ 时, 发现其不像其 if 或其它条件表达式一样会自动产生短路效应. 若各位刚好用到时请加以注意, 避免不必要的运行时错误.

    请见如下 Code:

    public static void SetPageInfo(BasePage page)
    {
        DataTable rights = GetOperationRights();

        var relatedRights = from right in rights.AsEnumerable()

                            where (right.Field<string>("module_code") == null || right.Field<string>("module_code").Equals(page.Module)) &&
                                  (right.Field<string>("function_group_code") == null || right.Field<string>("function_group_code").Equals(page.Group)) &&
                                  (right.Field<string>("function_key") == null || right.Field<string>("function_key").Equals(page.Member))

                            orderby right.Field<string>("module_code") descending,
                                    right.Field<string>("function_group_code") descending,
                                    right.Field<string>("function_key") descending

                            select new
                            {
                                CanQry = right.Field<decimal>("can_qry"),
                                CanNew = right.Field<decimal>("can_new"),
                                CanEdit = right.Field<decimal>("can_edt"),
                                CanDel = right.Field<decimal>("can_del")
                            };

        var relatedRight = relatedRights.FirstOrDefault();

        ...

    }

    当实际某 right.Field<string>("module_code") 为 null 时, 该 Code 会产生运行时错误. 故 where 子句需改成如下:

    where (right.Field<string>("module_code") == null || (right.Field<string>("module_code") ?? String.Empty).Equals(page.Module)) &&
          (right.Field<string>("function_group_code") == null || (right.Field<string>("function_group_code") ?? String.Empty).Equals(page.Group)) &&
          (right.Field<string>("function_key") == null || (right.Field<string>("function_key") ?? String.Empty).Equals(page.Member))

    令外, LINQ 中已把原 DBNull 转成 DotNet 的 null, 所以不用 Convert.IsDBNull(right.Field<string>("module_code")). 

     

  • UpdatePanel & UpdateProgress & Download File 的相关问题

          程序中有时会因要执行业务比较复杂, 运行时间长的一系统操作, 需要显示如 "执行中 .." 等用户友好提示,  可用ASP.NET AJAX 的 UpdatePanel & UpdateProgress 控件完成. 但若执行结果需要下载文件时, 则会出现执行完成但文件却下载不了的情况. 因为 UpdateProgress 是异步进行中.  解决方法可以建立一个 'DownloadFile.aspx' 页面作辅助, 请见如下主要代码片断  

    -------  Data.aspx ----------- 

    <asp:ScriptManager ID="ScriptManager" runat="server" /> 

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate> 

                   <asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="2" DynamicLayout="true">
                                <ProgressTemplate>
                                    <img src='<%=CommonUrl.Images %>wait_clock.gif' />
                                    <span id='spanProgressNote'></span>
                                </ProgressTemplate>
                  </asp:UpdateProgress>

             </ContentTemplate>
    </asp:UpdatePanel>  

     <script language="javascript">

            Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initializeRequestHandler);

            function initializeRequestHandler(sender, e) {
                var postBackElementId = e.get_postBackElement().id;

                switch (postBackElementId) {
                    case '<%= btnSearch.ClientID %>':
                        spanProgressNote.innerHTML = 'Loading ..';
                        break;

                    case '<%= imgExport.ClientID %>':
                        spanProgressNote.innerHTML = 'Exporting ..';
                        break;
                  }                      

             }       

    </script>

    -------  Data.cs ----------- 

    protected void imgExport_Click(object sender, ImageClickEventArgs e)
     {
            ...

           // SimpleWebUtils.DownloadFile(Response, filePath, Path.GetFileName(filePath));     // 不能直接在当前页下载文件 

            ScriptManager.RegisterStartupScript(this, this.GetType(), "RegisterStartupScript"
                                                    , String.Format("window.navigate('../Control/'DownloadFile.aspx?path={0}');", Server.UrlEncode(filePath)), true);


            //ScriptManager.RegisterStartupScript(this, this.GetType(), "RegisterStartupScript"
            //                                       , String.Format("window.navigate('{0}');", fileUrl), true);      // 用这种方式可以不用 ''DownloadFile.aspx' 页面但下载文件直接打开是用网页方式而不是实际文件方式 (如: Excel)

     }

    -------  DownloadFile.cs -----------

     protected void Page_Load(object sender, EventArgs e)
     {
            string path = Request.QueryString["path"];
            SimpleWebUtils.DownloadFile(Response, path, Path.GetFileName(path));
            ScriptManager.RegisterStartupScript(this, this.GetType(), "RegisterStartupScript", "window.close();", true);                                                
     }

  • 当心 Oracle Procedure 中的 IN 参数也会被你无意中修改了它的值

    在 Oracle Procedure 中使用 IN 参数似乎很好地对该参数起到保护作用, 其实不然! 请看如下 Code

    -- Spec Part 

    PACKAGE TEST
    IS
       g1   NUMBER;

       PROCEDURE proc1;

       PROCEDURE proc2 (p1 IN NUMBER);
    END;        

    -- Body Part

     PACKAGE BODY TEST
    IS
       PROCEDURE proc1
       IS
       BEGIN
          g1 := 1;
          proc2 (g1);
          DBMS_OUTPUT.put_line ('g1=' || g1);
       END;

       PROCEDURE proc2 (p1 IN NUMBER)
       IS
          c1   CONSTANT NUMBER := p1;
       BEGIN
          --p1 := p1 + 1;  这句是编译不通过的, 似乎已对 IN 参数保护了.
          DBMS_OUTPUT.put_line ('p1=' || p1);
          DBMS_OUTPUT.put_line ('c1=' || c1);
          g1 := g1 + 1;  -- 这句间接地改变了 IN 参数值!
          DBMS_OUTPUT.put_line ('after p1=' || p1);   -- 已经被改了!
          DBMS_OUTPUT.put_line ('after c1=' || c1); 
       END;
    END;

    运行 proc1 后输出:

    p1=1
    c1=1
    after p1=2
    after c1=1
    g1=2

    总结:

    1) 若要确保过程内任意地方都能访问到 IN 参数的初始值, 需要使用附加常量

    2) 尽可能少用全局变量 (风险很大)

    3) 其它非 Oracle 数据库也可能出现该情况.

     

    Posted Oct 08 2008, 03:29 PM by wego with no comments
    Filed under:
  • ASP.NET 自定义控件之解析标签内属性内嵌

    实现如下:

    <smic:Note runat=server ID='NoteInfo'>
         <b>Development Tools</b>
         <br />
         C#, JAVA, PHP
    </smic:Note>

    代码片段:

    [ToolboxBitmap(typeof(Label))]
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [ToolboxData("<{0}:Note runat=\"server\"></{0}:Note>"), DefaultProperty("Message"), ParseChildren(false), Designer("System.Web.UI.Design.WebControls.LabelDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    [ControlBuilder(typeof(LabelControlBuilder)), ControlValueProperty("Message"), DataBindingHandler("System.Web.UI.Design.TextDataBindingHandler, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    public class Note : WebControl
    {

            [PersistenceMode(PersistenceMode.InnerDefaultProperty), Bindable(true), Localizable(true)]       
            public string Message
            {
                get { return ViewState["Message"] as string; }
                set { ViewState["Message"] = value; }
            }

            protected override void AddParsedSubObject(object obj)        // 必须 Override WebControl 的 AddParsedSubObject 方法
            {
                if (this.HasControls())
                {
                    base.AddParsedSubObject(obj);
                }
                else if (obj is LiteralControl)
                {
                    this.Message = ((LiteralControl)obj).Text;
                }
                else
                {
                    string message = this.Message;
                    if (message.Length != 0)
                    {
                        this.Message = string.Empty;
                        base.AddParsedSubObject(new LiteralControl(message));
                    }
                    base.AddParsedSubObject(obj);
                }
            }

            protected override void Render(HtmlTextWriter output)
            {
                output.AddAttribute("class", "container");
                output.RenderBeginTag(HtmlTextWriterTag.Div);
                output.Write(this.Message);
                output.RenderEndTag();            
            }

    }

     

     

     

     

  • Lambda 不支持 yield

    今天将 Lambda 与 yield 结合起来使用, 结果编译不通过. (如下)

    public IEnumerable<int> DeletedIDs
    {
        get
        {
           
            var deletedIDs = new int[]{123, 456};

            Array.ForEach(deletedIDs, i => (yield return i));

        }
    }

    要写成如下:

    public IEnumerable<int> DeletedIDs
    {
        get
        {
            
           var deletedIDs = new int[]{123, 456};

           foreach (int deletedID in deletedIDs)
               yield return deletedID;
        }
    }

  • Oracle 处理数据高并发响应

    某些系统可能对系统应付数据高并发的响应要求比较高 (如: 飞行航空订票系统). 本文采用 Oracle 的 lock table 解决之.

    Procedure 中关键 code 如下:

    -------------------------------------------------------------

    lock table tb_book_ticket in share mode;

    ...

    insert into tb_book_ticket (id, scheduled_flight, ticket_no, book_time) values (ID.nextval, v_scheduled_flight, v_ticket_no, SYSDATE);    -- mark1

    ...    -- mark2

    select count(*) into v_book_count from tb_book_ticket where scheduled_flight = v_scheduled_flight;    -- mark3

    if v_book_count <= v_book_max_count then

        v_result := 'book successfully';

        commit;

    else

        v_result := 'book unsuccessfully';

        rollback;

    end if;

    return v_result;

    -------------------------------------------------------------

    以上有2个地方需注意:

    1) 采用 lock table table_name in share mode 方式而非 lock table table_name in exclusive mode 提高并发性处理, 尽量减少不必要执行等待.

    2) 按常规思路, 可能会将 mark1 与 mark3 顺序交换, 但此举不行

    -------------------------------------------------------------

    select count(*) into v_book_count from tb_book_ticket where scheduled_flight = v_scheduled_flight;    -- mark3

    ...    -- mark2

    if v_book_count < v_book_max_count then

        insert into tb_book_ticket (id, scheduled_flight, ticket_no, book_time) values (ID.nextval, v_scheduled_flight, v_ticket_no, SYSDATE);    -- mark1

         -- mark4

        commit;

    end if;

    -------------------------------------------------------------

    试想若 userA 执行到  mark4, 而同时 userB 执行到  mark3, 就可能会出现由于 userA  尚未commit 而导致 userB 订到机票但实际没有座位的情况.

    若确希望使用常规逻辑来实现, 需要用到 Oracle 的表的读锁功能 (精细访问策略), 而此非本文范围, 且其对于SYS用户无效.

     

    Posted Jul 03 2008, 09:00 AM by wego with no comments
    Filed under:
  • window.history.go(-N) 及页面自动刷新数据的解决方案

    使用情况:

    1) 用户在 [查询页] 选取所需的 DropDown 项或填写查询的 TextBox 值

    2) 点击结果表格的一条记录链接进入 [编辑页] (不是弹出 Form 形式, 而是整个页面跳转)

    3) 在 [编辑页] 中修改有关项后保存 (保存后可能又进行修改后又保存)

    4) 按 [Close] button 回 [查询页]

    5) 要求 [查询页] 保留之前的查询状态 (即各DropDown, TextBox 项保留用户刚才选取或录入的值), 而表格数据则要求自动刷新 (因为刚才在 [编辑页] 中可能作了某些修改)

     

    注意事项:

    1) 因为 HTTP 的无状态性, 所以采用 Session 保留页面间的信息传递 (注意: 不能使用 URL 传递方式, 如: window.location.href = 'Search.aspx?serverRefreshed=yes', 因为这样页面原状态将不可还原 )

    2) 由于 window.history.go(-N)  后页面的 cs 代码不会执行, 故采用 Ajax 方式调用服务端代码

     

    代码片断:

    ----------------------------------------------------

    Edit.aspx:

    <asp:HiddenField ID="hfPostCount" runat="server"/>
    <asp:button id="btnSave" runat="server" Text="Save" OnClientClick="document.getElementById(hfDataSaved).value = 'Yes'" OnClick="btnSave_Click"></asp:button>
    <input type=button id="btnClose" value="Close" onclick="FormClose();" />

    function FormClose()
    {  
        if (document.getElementById(hfDataSaved).value == 'Yes') RRSCore.SessionInfo.SetServerRefreshed("No");       
        var postCount = document.getElementById(hfPostCount).value;
        postCount++;
        window.history.go(-postCount);
    }       

    ----------------------------------------------------

    Edit.aspx.cs:

    protected void Page_Load(object sender, EventArgs e)
    {
       if (!this.IsPostBack)
           hfPostCount.Value = "0";
       else
           hfPostCount.Value = (int.Parse(hfPostCount.Value) + 1).ToString(); 

       Page.ClientScript.RegisterStartupScript(Page.GetType(), "SetClientVariable", "hfPostCount='" + this.hfPostCount.ClientID.ToString() + "';", true);  
    }

    ----------------------------------------------------

    Search.aspx  

    window.onload = function () {
        if (RRSCore.SessionInfo.GetServerRefreshed().value == 'No') document.forms[0].submit();              
        RRSCore.SessionInfo.SetServerRefreshed("Yes");
    }

    ----------------------------------------------------

    SessionInfo.cs (Ajax Source)

    namespace RRSCore

        public class SessionInfo
        { 

             [AjaxPro.AjaxMethod]
             public static void SetServerRefreshed(string serverRefreshed)
             {
                  HttpContext.Current.Session["ServerRefreshed"] = serverRefreshed;
             }

             [AjaxPro.AjaxMethod]
             public static string GetServerRefreshed()
             {
                   return HttpContext.Current.Session["ServerRefreshed"];
             }

        }

    }

    ----------------------------------------------------

  • Dot Net 2.0 使用3.5的 Linq

     注意事项:

    1) 前提是开发者机器要装有Framework 3.5, 引入Reference : System.Core

    2)  若发布服务器没装 Framework 3.5, 需手工把 System.Core.dll 加入到 bin 下再发布

    =========================================== 

    using System.Linq;

    ..

    string[] list = new string[] { "mary", "tom", "david", "cathy", "tom" };    // 除数组外,  其它集合类也可 (如: List, Hashtable , Dictionary)
    IEnumerable<string> result;

    //
    Console.WriteLine("--- 'FirstOrDefault' --");
    result = Enumerable.Where<string>(list,
                     delegate(string item)
                     {
                         return item == "tom";
                     });
    Console.WriteLine(Enumerable.FirstOrDefault(result));

    //
    Console.WriteLine("--- 'OrderBy' --");
    result = Enumerable.OrderBy<string, string>(list,
                    delegate(string item)
                    {
                        return item;
                    });
    foreach (string str in result)
    {
        Console.WriteLine(str);
    }

    //
    Console.WriteLine("--- 'Min' --");
    string result_str = Enumerable.Min<string, string>(list,
                     delegate(string item)
                     {
                         return item;
                     });
    Console.WriteLine(result_str);

    //
    Console.WriteLine("--- 'Distinct' --");
    result = Enumerable.Distinct<string>(list);
    foreach (string str in result)
    {
        Console.WriteLine(str);
    }

    //
    Console.WriteLine("--- 'All' --");
    bool result_bool = Enumerable.All<string>(list, delegate(string item)
                     {
                         return item.CompareTo("d") > 0;
                     });
    Console.WriteLine(result_bool);

    //
    Console.WriteLine("--- 'Distinct' & 'OrderBy' & 'Where' --");
    result = Enumerable.Distinct<string>(Enumerable.OrderBy<string, string>(Enumerable.Where<string>(list,
                    delegate(string item)
                    {
                        return item == "tom" || item == "david";
                    }),
                    delegate(string item)
                    {
                        return item;
                    }));
    foreach (string str in result)
    {
        Console.WriteLine(str);
    }

    ===========================================

    输出如下: 

    --- 'FirstOrDefault' --
    tom
    --- 'OrderBy' --
    cathy
    david
    mary
    tom
    tom
    --- 'Min' --
    cathy
    --- 'Distinct' --
    mary
    tom
    david
    cathy
    --- 'All' --
    False
    --- 'Distinct' & 'OrderBy' & 'Where' --
    david
    tom
     

     

    Posted May 14 2008, 01:38 PM by wego with no comments
    Filed under: ,
  • Oracle 泛型使用

    ------------------------------------------------------------------------------------------------------------- 

    --  procedure part

    FUNCTION IIF (p_bool IN BOOLEAN, p_result1 IN ANYDATA, p_result2 IN ANYDATA)
       RETURN ANYDATA
    IS
       atype                ANYTYPE;
       data_type_argument   EXCEPTION;
    BEGIN
       IF p_result1.gettype (atype) <> p_result2.gettype (atype)
       THEN
          RAISE data_type_argument;
       END IF;

       CASE p_result1.gettype (atype)
          WHEN DBMS_TYPES.typecode_number
          THEN
             RETURN CASE
                WHEN p_bool
                   THEN ANYDATA.convertnumber (p_result1.accessnumber)
                ELSE ANYDATA.convertnumber (p_result2.accessnumber)
             END;
          WHEN DBMS_TYPES.typecode_varchar2
          THEN
             RETURN CASE
                WHEN p_bool
                   THEN ANYDATA.convertnvarchar2 (p_result1.accessvarchar2)
                ELSE ANYDATA.convertnvarchar2 (p_result2.accessvarchar2)
             END;
          WHEN DBMS_TYPES.typecode_date
          THEN
             RETURN CASE
                WHEN p_bool
                   THEN ANYDATA.convertdate (p_result1.accessdate)
                ELSE ANYDATA.convertdate (p_result2.accessdate)
             END;
       END CASE;
    EXCEPTION
       WHEN data_type_argument
       THEN
          DBMS_OUTPUT.put_line
              ('The data type of the ''IIF'' function both result parameter is different');
          RETURN NULL;
    END;

     

    -------------------------------------------------------------------------------------------------------------

    --  caller part 

    v_str                   VARCHAR2 (50)
             := iif (1 > 2,
                     ANYDATA.convertvarchar2 ('Yes'),
                     ANYDATA.convertvarchar2 ('No')
                    ).accessnvarchar2;         

    -- 类似于 C# 使用 string v_str = iif<string> (1> 2, 'Yes', 'No');


    v_num                NUMBER
             := iif (1 > 2, ANYDATA.convertnumber (1), ANYDATA.convertnumber (0)).accessnumber;   

    -- 类似于 C# 使用 int v_num = iif<int> (1> 2, 1, 0);

     

    DBMS_OUTPUT.put_line (v_str);       -- output 'No' 

    DBMS_OUTPUT.put_line (v_num);     -- output '0'

                                                                                      

     

     

    Posted May 07 2008, 11:48 AM by wego with no comments
    Filed under:
  • 数学对编程的重要

    且看如下2

     (1) 算出1加到100的总和。  

         低效:             

                 int sum = 0;        

                 for (int i=1; i<=100; i++)   

                    sum += i;

         高效:                          
               int sum = ((1 + 100) * (100 - 1 + 1)) / 2; 
    或更精简的 int sum = (101 * 100) >> 2;    

      (2) 计算1加到10000,奇数和偶数的总和。

       低效: 

             int oddSum = 0;                            
             
     int evenSum = 0;                           
             
     for (int i=1; i<=10000; i++)                          
            
     {                                                  
                  
    if (i % 2 == 0)                                                                       
                        
    evenSum += i;                                               
                  

               else
              oddSum += i;
             } 
             

      高效:                  

              int sum = (10001 * 10000) >> 2;                       
               
    int evenSum = 5001 * 5000;                         
             int oddSum = sum - evenSum; 
     

        1
    10000之间的偶数总和是是2+4+6+...+10000,把它们全部除以2的话会变成1+2+3+...+5000,所以110000偶数的总和不就是1加到5000的两倍   
     ---------------------------------------------
     
        

    可见
    ,  千万不要把曾经和你相伴十多年的数学课程知识给遗忘掉噢 !!

     

  • ASP.NET Download Web File

    今天写了个 DownloadWebFile 函数,  采用 读取 --> 输出 方式.  但发现当第二次打开 Download 的文件时, 文件报已损坏错误. code 如下:

    protected void DownloadFile(string url)
      {
       System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); 
       System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
       Stream respStream = myrp.GetResponseStream();

       Response.Expires = 0;
       Response.Clear();

       Response.ContentType = myrp.ContentType;

       const int BUFFER_SIZE = 16*1024;
       byte[] buffer = new byte[BUFFER_SIZE];
       int length;   
       
       length = respStream.Read(buffer, 0, BUFFER_SIZE);
       while(length > 0)
       {
          Response.BinaryWrite(buffer);   
          length = respStream.Read(buffer, 0, BUFFER_SIZE);
       }

       Response.AddHeader("content-disposition", String.Format("attachment;filename={0}", "Competitor's list.xls"));
       Response.AddHeader("pragma", "no-cache");
       Response.AddHeader("expires", "0");
       Response.AddHeader("cache-control", "must-revalidate, post-check=0, pre-check=0");   

       Response.Flush();
       Response.End();   
      }

     后在 Wicky 同志的帮助下,  采用 读取 --> 中传站存放 -> 输出 方式得已解决 !

    protected void DownloadFile(string url)
      {
       System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); 
       System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
       Stream respStream = myrp.GetResponseStream();

       Response.Expires = 0;
       Response.Clear();

       Response.ContentType = myrp.ContentType;

       const int BUFFER_SIZE = 16*1024;
       byte[] buffer = new byte[BUFFER_SIZE];
       int length;   
       
       MemoryStream ms = new MemoryStream();
       
       length = respStream.Read(buffer, 0, BUFFER_SIZE);
       while(length > 0)
       {
          ms.Write(buffer, 0, length);
          length = respStream.Read(buffer, 0, BUFFER_SIZE);
       }

       Response.AddHeader("content-disposition", String.Format("attachment;filename={0}", "Competitor's list.xls"));
       Response.AddHeader("pragma", "no-cache");
       Response.AddHeader("expires", "0");
       Response.AddHeader("cache-control", "must-revalidate, post-check=0, pre-check=0");   

       Response.BinaryWrite(ms.GetBuffer());

       Response.Flush();
       Response.End();   
      }

     

     

     

  • FireBird 求指定行数记录

    数据库 FireBird 求指定行数记录的 sql 语法不是Oracle的rownum,也不是SQL Server的Top n.  而是使用以下比较特别的形式.

    1)  select First 2 skip 3 * from table1 order by field1 desc     -- 取第4行到第5行

    2)  select * from table1 order by field1 desc ROWS 2 TO 4   -- 取第2行到第4行

    3)  select First 3 skip 0 * from table1 order by field1 desc     -- 同 SQL Server 的 Top 3 

    First n skip m形式会在忽略掉m行后,取前n行;

    而rows m to n形式,则是从第m行取到第n行。

More Posts Next page »
Copyright SDT, 2006-2009. All rights reserved.