none
多個資料Table搜尋方法? RRS feed

  • 問題

  • 作業系統:
    Windows 8 >

    IIS與Asp.Net版本:
    <IIS8>
    < Asp.Net  3.5  >

    開發工具:
    <Visual Studio , 2008>
    VB.NET

    資料庫版本:
    <SQL 2008>

    狀況描述 :

    我有一個123.mdf 資料庫. 裡面有將近上百個 table

    我使用一個textbox 來做模糊搜尋

    如果使用

    dim aaa as string =textbox.text

    select * form xxx  where 內容 like aaa

    這個方法 那需要寫實在是太麻煩了 爾且效能也非常不好

    請問是否有其它的方法 可以搜尋

    像是全文檢索 那樣 ?

    謝謝了 !

    2013年1月3日 上午 07:37

解答

  • 不好意思 請問

    使用SYS.TABLES 要如何提取 NAME 裡面的資料

    我的想法 是使用SYS.COUNT 算出資料行

    帶入迴圈 

    再將NAME 中的資料成為變數 帶入搜尋的範圍

     ds.SelectCommand = "select NAME from sys.views WHERE NAME='XXXX' "

    但是 我不知道 NAME 裡的資料怎麼提取

    謝謝 !

    Sorry,記錯指令。

    用SELECT * FROM 資料庫Name.INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE' 去找。

    Table_Name就是該資料庫全部的資料表的名稱。

    • 已標示為解答 SaberTang 2013年1月8日 上午 09:20
    2013年1月4日 上午 10:37

所有回覆

  • 你的意思是,這個要模糊搜尋的內容,要針對所有table的所有欄位進行搜尋?

    也就是不固定table, 不固定欄位?

    麻煩您講清楚一點,另外自己發問完請review一遍,把文法跟錯字的問題修正。


    授人以魚,三餐之需;授人以漁,終生之用。
    希望各位發問的朋友,得到的是如何釣魚的知識。之後也可以分享給別人,釣魚的知識。而不是肚子餓了,就上來討魚吃。

    若您的程式碼有SQL injection的問題,在修改完畢之前,我不願意給您任何解答。因為解決了您的程式問題,造成更大的系統漏洞問題,還不如讓程式壞掉。

    請參考:SQL injection簡介與解決方式

    常用資源參考:


    小弟的blog: In 91,wiki: my wiki

    2013年1月3日 上午 07:43
    版主
  • 不好意思

    模糊搜尋的[內容] 是指欄位的名稱

    所以當使用者在textbox 中keyin "螺絲"2個字的時候

    程式會搜尋所有table 中的[內容] 欄位 只要有"螺絲" 2個字 就顯示到gridview 中

    也就是不固定table, 固定欄位

    謝謝


    • 已編輯 SaberTang 2013年1月3日 上午 08:12
    2013年1月3日 上午 08:11
  • 你如果要在RDBMS中這樣用,通常會針對這樣的需求建立反正規化的table,來加速搜尋時不用撈一堆table,但看起來這「所有table」的資料都要反正規化,應該也是要命的動作。

    比較好奇的是,為什麼會有這樣的需求?您能不能把商業邏輯上的需求明確一點描述一下呢?

    否則您這搜尋的需求,可能要走 Lucene.net 之類的比較好做,可以參考當麻的簡介文章:http://www.dotblogs.com.tw/junegoat/Tags/Lucene/default.aspx


    授人以魚,三餐之需;授人以漁,終生之用。
    希望各位發問的朋友,得到的是如何釣魚的知識。之後也可以分享給別人,釣魚的知識。而不是肚子餓了,就上來討魚吃。

    若您的程式碼有SQL injection的問題,在修改完畢之前,我不願意給您任何解答。因為解決了您的程式問題,造成更大的系統漏洞問題,還不如讓程式壞掉。

    請參考:SQL injection簡介與解決方式

    常用資源參考:


    小弟的blog: In 91,wiki: my wiki

    2013年1月3日 上午 08:52
    版主
  • 91 你好

    因為公司要針對產品產生序號 序號共有10碼 分為前三碼 中間三碼 以及尾四碼

    前三碼內共有20個item A01~A20

    A01中又有10個ITEM (中間三碼) 100~900 以此類推~A20

    而100(中間三碼) 內又有無數的ITEM (0001~9999) 尾四碼

    例如 A01-100-0001

    A01 -> 消耗品

    100 -> 文具

    0001 -> 筆

    將資料正規化後 就產生了上百個TABLE

    不知我這樣想是否正確 ?

    然爾筆 未必只出現在消耗品類或文具類 也會出現在別的類別

    所以才想要有這方面的需求 當輸入"筆" 關鍵字後 會把類似筆的資料都撈出來

    我也想過.乾脆把所有的資料先全部丟到一個TABLE 內.再搜尋

    或是 程式碼 就一個一個KEY   SELECT * FROM xxx  left join xxx

    我也想過用SQL 的全文檢索使用 但是我使用的版本是EXPRESS版 沒有這一個功能

     不知是否還有更好的方法 ?

    謝謝 !

     

    2013年1月3日 上午 09:26
  • 我記得全文檢索也是要一個一個Table自己搜尋,它只是會做斷字斷詞而已。

    你要這樣搜尋的話,自己用sys.columns去找有特定欄位名的Table,再跑迴圈select

    2013年1月3日 上午 10:01
    版主
  • 基本上,你的資料表示整個分開成數百個,效能上很難跟一個TABLE的狀況比。

    一個就是如阿尼大講的,寫一個Stored Procedures,裡面就先用透過sys.tables 找出全部的Table,並且過濾後用迴圈對每個Table做搜尋,再合起來

    另一個就是接近方法一所說,寫一個SP,透過sys.tables把全部的資料利用迴圈合併起來放在一個Temp Table,然後直接針對這個TABLE做搜尋,
    而可以用排程的方式,例如每一個小時更新一次這個Temp Table,但這個就不會這麼即時性,以及要根據你自己的資料內容來決定週期為何。

    再不然另一種就是前置工作比較大,但又即時性的話,
    就是針對每個Table都去寫Insert, update,delete 的trigger ,然後都會Trigger到一個總表一樣的Table,之後你的查詢只要查詢這個總表即可。
    trigger的話,你可以先確定好範本後,一樣的透過sys.tables迴圈的方式,去產生每個Table的語法,之後再複製這些語法來執行會稍微方便一點點點。

    2013年1月3日 上午 11:00
  • 是既有的系統了嗎?

    如果不是,建議您重新思考正規化的方式

    以您的舉例:筆,可能出現在消耗品,也可能出現在文具類,但從產品來看,它就是筆,所以也應該僅有一個產品SN

    而筆出現在消耗品、文具類只是在於同一個產品它可以分屬在不同分類中,因此思考的是它是一個1對多(產品對多個分類)的關係

    那麼一來Table也就不至於上百張了

    如果已經是既有的系統了,那麼您也可以依上述規則,在中間夾一層進行資料的還原及重新正規化,然後您的程式只要針對中間這一層去做查詢

    以上是我的想法,供您參考


    軟體開發領域裡區區一個迷途工程師
    MyBlog: http://www.dotblogs.com.tw/ian/
    開發ASP.NET您要瞭解的基楚

    2013年1月4日 上午 01:56
    版主
  • 謝謝各位的解答

    我先試一下

    謝謝!

    2013年1月4日 上午 02:14
  • 謝謝你的解答 既然有了方向我再try try 看

    謝謝

    2013年1月4日 上午 09:02
  • 不好意思 請問

    使用SYS.TABLES 要如何提取 NAME 裡面的資料

    我的想法 是使用SYS.COUNT 算出資料行

    帶入迴圈 

    再將NAME 中的資料成為變數 帶入搜尋的範圍

     ds.SelectCommand = "select NAME from sys.views WHERE NAME='XXXX' "

    但是 我不知道 NAME 裡的資料怎麼提取

    謝謝 !

    2013年1月4日 上午 10:10
  • 由於我還是新手

    所以你所建議的方向這個概念我還有點模糊

    而正規畫的方式 都是我從書上一步一步學來的

    所以概念還很薄淺  現在仍在努力中

    非常感謝你的解答

    謝謝!

    2013年1月4日 上午 10:18
  • 不好意思 請問

    使用SYS.TABLES 要如何提取 NAME 裡面的資料

    我的想法 是使用SYS.COUNT 算出資料行

    帶入迴圈 

    再將NAME 中的資料成為變數 帶入搜尋的範圍

     ds.SelectCommand = "select NAME from sys.views WHERE NAME='XXXX' "

    但是 我不知道 NAME 裡的資料怎麼提取

    謝謝 !

    Sorry,記錯指令。

    用SELECT * FROM 資料庫Name.INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE' 去找。

    Table_Name就是該資料庫全部的資料表的名稱。

    • 已標示為解答 SaberTang 2013年1月8日 上午 09:20
    2013年1月4日 上午 10:37
  • 不好意思再請問一下

    我想搜尋資料庫後. 然後將搜尋到的資料新增gridview 中該如何做呢 ?

            Dim ds As New System.Web.UI.WebControls.SqlDataSource
            Dim dst As New System.Web.UI.WebControls.SqlDataSource
            Dim sqlstr As String 

            If TextBox1.Text <> "" Then
                sqlstr = "and 名稱 like '%" & TextBox1.Text & "%'"
            End If

    ' 將檢視表的table_name 填入當作變數搜尋

            ds.ConnectionString = conStr
            dst.ConnectionString = conStr
            ds.SelectCommand = "select NAME from sys.views WHERE 1=1 "

    ' 將搜尋的資料填入

            Dim aaa As DataView = ds.Select(New DataSourceSelectArguments)
            Dim BBB As Integer = aaa.Count

    '使用迴圈方式一一的搜尋table內的資料

            Dim a As Integer
            For a = 0 To BBB - 1

           Dim DDD As String = aaa.Item(a).Row.Item(0).ToString
           dst.SelectCommand = "SELECT * FROM " & DDD & " WHERE 1=1" & sqlstr

           GridView1.DataSource = dst.Select(New DataSourceSelectArguments)
           GridView1.DataBind()

           next

    但是這個方法只能顯示最後一個table 的資料

    所以我需要 每搜尋到一筆相符的資料後

    新增到GridView 中

    但是 我不知道要怎樣提取資料 然後新增

    提取資料庫的資料是要用DataTable 嗎? 還是用DataSet 的方式呢? 還是都是錯的 ?

    請指教了

    謝謝了 !!

     

    2013年1月8日 上午 04:21
  • 先解決 SQL injection 的問題比較實際一點。

    授人以魚,三餐之需;授人以漁,終生之用。
    希望各位發問的朋友,得到的是如何釣魚的知識。之後也可以分享給別人,釣魚的知識。而不是肚子餓了,就上來討魚吃。

    若您的程式碼有SQL injection的問題,在修改完畢之前,我不願意給您任何解答。因為解決了您的程式問題,造成更大的系統漏洞問題,還不如讓程式壞掉。

    請參考:SQL injection簡介與解決方式

    常用資源參考:


    小弟的blog: In 91,wiki: my wiki

    2013年1月8日 上午 04:25
    版主
  • 謝謝你的指示

    這方面我不是那麼了解

    由於程式是只用在公司的區網內使用

    加上之後會使用篩選字的方式

     If InStr(1, u_input, "--") <> 0 Or InStr(1, u_input, "1=1") <> 0 Then
                Return True
            End If

    類似的方式來做

    謝謝你

    2013年1月8日 上午 06:32
  • 不好意思再請問一下

    我想搜尋資料庫後. 然後將搜尋到的資料新增gridview 中該如何做呢 ?

            Dim ds As New System.Web.UI.WebControls.SqlDataSource
            Dim dst As New System.Web.UI.WebControls.SqlDataSource
            Dim sqlstr As String 

            If TextBox1.Text <> "" Then
                sqlstr = "and 名稱 like '%" & TextBox1.Text & "%'"
            End If

    ' 將檢視表的table_name 填入當作變數搜尋

            ds.ConnectionString = conStr
            dst.ConnectionString = conStr
            ds.SelectCommand = "select NAME from sys.views WHERE 1=1 "

    ' 將搜尋的資料填入

            Dim aaa As DataView = ds.Select(New DataSourceSelectArguments)
            Dim BBB As Integer = aaa.Count

    '使用迴圈方式一一的搜尋table內的資料

            Dim a As Integer
            For a = 0 To BBB - 1

           Dim DDD As String = aaa.Item(a).Row.Item(0).ToString
           dst.SelectCommand = "SELECT * FROM " & DDD & " WHERE 1=1" & sqlstr

           GridView1.DataSource = dst.Select(New DataSourceSelectArguments)
           GridView1.DataBind()

           next

    但是這個方法只能顯示最後一個table 的資料

    所以我需要 每搜尋到一筆相符的資料後

    新增到GridView 中

    但是 我不知道要怎樣提取資料 然後新增

    提取資料庫的資料是要用DataTable 嗎? 還是用DataSet 的方式呢? 還是都是錯的 ?

    請指教了

    謝謝了 !!

     

    發覺這個方法好像不行 !

    不知有沒有其他的方法呢 ?

    2013年1月8日 上午 06:35
  • 你把所有的資料UNION起來就行了
    2013年1月8日 上午 08:45
    版主
  • 1.如果sql injection那麼容易用幾個過濾條件就可以防範,那我覺得您還是好好去了解一下吧(本區置頂文就有資料)

    2.sql injection不會因為是內網就少了威脅


    軟體開發領域裡區區一個迷途工程師
    MyBlog: http://www.dotblogs.com.tw/ian/
    開發ASP.NET您要瞭解的基楚

    2013年1月8日 上午 08:56
    版主
  • 謝謝阿尼大大的回覆

    2013年1月8日 上午 09:16
  • 謝謝No.18 的回覆
    2013年1月8日 上午 09:18
  • 謝謝各位熱心的指教.

    針對此搜尋的問題 .我使用了一些很笨的土法煉鋼方法

    寫了幾個迴圈去讀.然後一個一個的貼

    這個效率很差.

    所以還是聽 阿尼大的方法全部union 起來好了

    謝謝

    2013年1月8日 上午 09:27
  • 一種就是一次先把SQL 整個準備好,然後做一次搜尋。

    另一種可以在For 迴圈外, 先New 一個Table

    然後再迴圈裡搜尋出來的結果加入到這個TABLE裡。

    之後再For 迴圈外面才做DataSource的指定與 DataBind 

    哪種方法好,或效能好,就要看你的資料狀況而定。

    2013年1月9日 上午 02:11
  • 謝謝解答 !

    2013年1月9日 上午 10:24