顯示具有 SQL 標籤的文章。 顯示所有文章
顯示具有 SQL 標籤的文章。 顯示所有文章

2012年9月26日 星期三

下載或刪除儲存在資料庫的檔案_ashx泛型處理常式

使用泛型處理常式 download.ashx 來下載儲存於資料庫欄位中的資料。
此檔案會從被呼叫的網址收集scid參數,當成資料庫下載的主要鍵



<%@ WebHandler Language="VB" Class="download" %>
'----------------------------------------------------------------------------
'程式功能 檔案上傳下載 (以資料庫存放檔案) > 檔案下載
'----------------------------------------------------------------------------
Imports System
Imports System.Data.SqlClient
Imports System.Web
Imports System.Web.Configuration
Imports System.Web.SessionState     ' 要使用 Session 必需加入此命名空間
Public Class download : Implements IHttpHandler, IRequiresSessionState
   
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        'context.Response.ContentType = "text/plain"
        'context.Response.Write("Hello World")
       
        Dim mErr As String = ""
        Dim scid2 As Integer = -1

        ' 檢查使用者權限,但不存入登入紀錄
        'Check_Power("2002", False, context)
       
        If context.Request("scid") IsNot Nothing Then
            If Integer.TryParse(context.Request("scid").Trim(), scid2) Then
                ' 處理下載檔案
                Using Sql_conn As New SqlConnection(WebConfigurationManager.ConnectionStrings("AppSysConnectionString").ConnectionString)
                    Sql_conn.Open()
                   
                    Using Sql_Command As New SqlCommand()
                        Dim SqlString As String = ""
                       
                        SqlString = "Select Top 1 fname, ftype, fcontent From 學生證照2 Where scid2 = @scid2"
                       
                        Sql_Command.Connection = Sql_conn
                        Sql_Command.CommandText = SqlString
                        Sql_Command.Parameters.AddWithValue("scid2", scid2)
                       
                        Dim Sql_Reader As SqlDataReader = Sql_Command.ExecuteReader()
                       
                        If Sql_Reader.Read() Then
                            Dim fcontent As Byte() = DirectCast(Sql_Reader("fcontent"), Byte())
                           
                            context.Response.Clear()
                            context.Response.Charset = "utf-8"
                           
                            ' 檔名要先編碼,中文檔名才不會有問題
                            context.Response.AddHeader("Content-Disposition", "inline;filename=" & context.Server.UrlEncode(Sql_Reader("fname").ToString().Trim()))
                            context.Response.ContentType = Sql_Reader("ftype").ToString()
                            context.Response.BinaryWrite(fcontent)
                            context.Response.End()
                        Else
                            mErr = "找不到這個檔案的資料!\n"
                        End If
                    End Using
                End Using
            Else
                mErr = "參數傳送有問題!\n"
            End If
        Else
            mErr = "參數傳送有問題!\n"
        End If
       
        If mErr <> "" Then
            context.Response.ContentType = "text/html"
            context.Response.Write(mErr)
            context.Response.End()
        End If
    End Sub

   Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class


而另外有一個  filedelete_download.aspx 來呼叫剛剛撰寫的 download.ashx 。


傳遞網址 download.ashx?scid={0}  {0}代表的是DataNavigateUrlField的資料,也就是資料表中的主要鍵欄位。
點選下載後,如果是圖形會直接開新視窗顯示圖片,如果是其他檔案會詢問開啟, 儲存 或 取消


當我們要實作刪除功能時,首先必須修改 sqldatasource ,設定sqldatasource資料來源時,刪除delete指令需要修改,改成 
DELETE FROM [學生證照2] WHERE [scid2] = @original_scid2

接著從 gridview 啟用刪除即可,必要時可用編輯資料行調整左右位置

檔案上傳asp.net

檔案上傳一直是教書以來想要完成的事,可是大部分的書都叫讀者上傳到伺服器的某個資料夾儲存,這會是一個嚴重的問題。這學期教資料庫剛好複習一下,這次使用Visaul Studio 2010,是 ASP.NET 4.0,應該可以用個幾年吧。

1. 首先在設計模式布置FileUpload(負責選取檔案), textbox(負責輸入檔案描述,可空白),Button(負責驅動上傳), Literal(負責上傳後顯示資訊),而Label物件可以不用放。
而對應要儲存檔案的資料表設計如下, fcontent負責儲存檔案內容,ftype負責檔案類型,fsize檔案大小,fname檔案全名(包括附檔名),fext負責附檔名,fdesc是檔案的描述說明, fuploadtiem存上傳的日期時間。
而程式碼uploadfile.aspx.vb的內容如下

Imports System.Data.SqlClient
Imports System.Web.Configuration
Imports System.IO
Partial Class Default4
    Inherits System.Web.UI.Page
    Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
        Dim icnt As Integer = 0, jcnt As Integer = 0
        Dim sqlstring As String = "", merr As String = ""
        Dim fname As String = "", fext As String = "", ftype As String = "", fsize As Integer = 0, fdesc As String = "", fuploadtime As DateTime = DateTime.Now
        '處理上傳檔案、說明及檔案內容存入資料庫
        Using sql_conn As New SqlConnection(WebConfigurationManager.ConnectionStrings("APPSYSConnectionString").ConnectionString)
            sql_conn.Open()
            Using sql_command As New SqlCommand()
                '儲存檔案
                'For icnt = 1 To Request.Files.Count
                Dim fu_file As FileUpload = DirectCast(Page.FindControl("fu_file"), FileUpload)
                Dim tb_file As TextBox = DirectCast(Page.FindControl("tb_file"), TextBox)
                If fu_file.HasFile Then
                    jcnt = jcnt + 1
                    fname = fu_file.FileName
                    fext = Path.GetExtension(fname).ToString()
                    fsize = fu_file.PostedFile.ContentLength
                    Response.Write(fsize)
                    If fsize > 1024000 Then
                        merr = "檔案超過1MB"
                    End If
                    ftype = fu_file.PostedFile.ContentType
                    fdesc = tb_file.Text.Trim()
                    '檔案存入資料庫
                    sqlstring = "insert into 學生證照2 " & "(fname, fext, ftype, fsize, fdesc, fcontent, fuploadtime)"
                    sqlstring &= " values (@fname, @fext, @ftype, @fsize, @fdesc, @fcontent, @fuploadtime)"
                    sql_command.Parameters.Clear()
                    sql_command.CommandText = sqlstring
                    sql_command.Connection = sql_conn
                    sql_command.Parameters.AddWithValue("fname", fname)
                    sql_command.Parameters.AddWithValue("fext", fext.ToLower())
                    sql_command.Parameters.AddWithValue("ftype", ftype)
                    sql_command.Parameters.AddWithValue("fsize", fsize)
                    sql_command.Parameters.AddWithValue("fdesc", fdesc)
                    'fuploadtime是以client的系統時間為準
                    sql_command.Parameters.AddWithValue("fuploadtime", fuploadtime)
                    sql_command.Parameters.AddWithValue("fcontent", fu_file.FileBytes)
                    If merr = "" Then
                        sql_command.ExecuteNonQuery()
                    End If
                Else
                    merr = "沒有選擇任何上傳的檔案!"
                End If

                ' Next

            End Using

        End Using
        'msg_close()呼叫寫在aspx的javascript副程式,javascript必須寫在<head>與</head>中間
        '為了減少複雜性,我將msg_close()的指令去掉了
        If merr <> "" Then
            '顯示錯誤訊息
            lt_show.Text = "<script language=javascript>alert(""" & merr & """);</script>"
        Else
            '完成上傳,返回瀏覽頁
            lt_show.Text = "<script language=javascript>alert(""資料上傳完成!\n"");location.replace(""filedelete_download.aspx"");</script>"
            'lt_show.Text &= "location.replace(""Default5.aspx"");</script>"
        End If

    End Sub
End Class





另外要一提的是預設上傳檔案有大小限制,經過測試約在4MB左右,
因此在web.config <system.web>與 </system.web>之間,加上此行程式(改變上限為10MB) <httpRuntime maxRequestLength="10240"/>
如果超過10MB,瀏覽器的畫面會出現無法顯示網頁

為了避免此畫面,所以網頁可以允許上傳<1MB的檔案,但因為原本uploadfile.aspx.vb中,有小於1MB的條件
  If  fsize > 1024000 Then
                        merr = "檔案超過1MB"
  End If



除了檔案大小外,也可透過限制使用者上傳檔案的附檔名來避免發生太大的檔案,可以google查到使用java script來限制,將原本uploadfile.aspx的html修改,從原本
<asp:FileUpload ID="fu_file" runat="server" /> 改成
 <asp:FileUpload ID="fu_file" runat="server" onchange="return checkFileExtension(this);"/>
此外,將下列指令放在 uploadfile.aspx 原始檔<head>與</head>中,


    <script type="text/javascript">
        function checkFileExtension(elem) {
            var filePath = elem.value;
            if (filePath.indexOf('.') == -1) {
                remove(elem);
                alert('不正確的副檔名格式');
                return false;
            }
            var validExtensions = new Array();
            var ext = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase();
            //限制只能選取那些副檔名
            validExtensions[0] = 'jpg';
            validExtensions[1] = 'pdf';
            validExtensions[2] = 'doc';
            validExtensions[3] = 'docx';
            validExtensions[4] = 'jpeg';
            for (var i = 0; i < validExtensions.length; i++) {
                if (ext == validExtensions[i])
                    return true;
            }
            remove(elem);
            alert('不正確的副檔名格式: ' + ext.toUpperCase());
            return false;
        }
        function remove(control) {
            var who = control;
            who.value = "";
            var who2 = who.cloneNode(false);
            who2.onchange = who.onchange;
            who.parentNode.replaceChild(who2, who);
        }
</script>

2012年9月24日 星期一

visual studio 2010製作master-detail一對多資料表


新版的powercam6已經可以上傳到youtube了,終於表示使用powercam錄的影片可以進一步作後製,雖然powercam還有一些缺點(解析度的限制),不過聊勝於無,以下是我在visual studio 2010製作master-detail一對多資料表的查詢步驟。

2012年9月23日 星期日

SQL Server Management Studio資料表變更設計後無法存檔的解法

在Management Studio中修改了某一張資料表,設定主要鍵欄位後照以往經驗按存檔,沒想到竟然出現錯誤畫面說不允許儲存變更,趕緊上網找解法


SQL Server Management Studio資料表變更設計後無法存檔的解法
原來要從功能表中的選項


















接著在選項的畫面中,選擇設計師/資料表和資料庫設計工具,將 防止儲存需要資料表重建的變更 取消勾選 即可。



判斷sql server版本

這學期教資料庫管理系統,常常要接觸一些sql server的問題,這次要記錄的是如何判斷目前正在執行的sql server版本?
可以在sql server management tool介面中執行 sql 指令

分別是三個指令
SELECT SERVERPROPERTY('productversion')
SELECT SERVERPROPERTY ('productlevel')
SELECT SERVERPROPERTY ('edition')


SQL Server 2008
  • 產品版本 (例如,10.0.1600.22)
  • 產品等級 (例如,RTM)
  • 版本 (例如,Enterprise)
SQL Server 2005
  • 產品版本 (例如,9.00.1399.06)
  • 產品等級 (例如,RTM)
  • 版本 (例如,Enterprise Edition)
RTM2005.90.1399
SQL Server 2005 Service Pack 12005.90.2047
SQL Server 2005 Service Pack 22005.90.3042
SQL Server 2005 Service Pack 32005.90.4035
RTM 2005.90.1399
SQL Server 2005 Service Pack 1 2005.90.2047
SQL Server 2005 Service Pack 2 2005.90.3042
SQL Server 2005 Service Pack 3 2005.90.4035
RTM2005.90.1399
SQL Server 2005 Service Pack 12005.90.2047
SQL Server 2005 Service Pack 22005.90.3042
SQL Server 2005 Service Pack 32005.90.4035



 SQL Server 2000
  • 產品版本 (例如:8.00.534)
  • 產品等級 (例如:「RTM」或「SP2」)
  • 版本 (例如:Standard Edition)。
  • 2012年9月21日 星期五

    前幾天試著將SQL Server 2008的資料庫附加上去,竟然出現錯誤,訊息是附加失敗,錯誤代碼5120,以前都沒有出現過,趕緊上網查詢,終於找到解法