Does MS access(2003) have anything comparable to Stored procedure. I want to run a complex query in MS acceess

前端 未结 10 1535
无人及你
无人及你 2020-12-03 21:49

I have a table, call it TBL. It has two columns,call them A and B. Now in the query I require one column as A and other column should be a comma seprated list of all B\'s wh

相关标签:
10条回答
  • 2020-12-03 22:33

    @Remou on DHookom's Concatenate function: neither the SQL standard nor the Jet has a CONCATENATE() set function. Simply put, this is because it is a violation of 1NF. I'd prefer to do this on the application side rather than try to force SQL to do something it wasn't designed to do. Perhaps ACE's (Access2007) multi-valued types is a better fit: still NFNF but at least there is engine-level support. Remember, the question relates to a stored object: how would a user query a non-scalar column using SQL...?

    @David W. Fenton on whether Jet has stored procedures: didn't you and I discuss this in the newsgroups a couple of years ago. Since version 4.0, Jet/ACE has supported the following syntax in ANSI-92 Query Mode:

    CREATE PROCEDURE procedure (param1 datatype[, param2 datatype][, ...]) AS sqlstatement;
    
    EXECUTE procedure [param1[, param2[, ...]];
    

    So Jet is creating and executing something it knows (in one mode at least) as a 'procedure' that is 'stored' in the MDB file. However, Jet/ACE SQL is pure and simple: it has no control-of-flow syntax and a PROCEDURE can only contain one SQL statement, so any procedural code is out of the question. Therefore, the answer to whether Jet has stored procedures is subjective.

    0 讨论(0)
  • 2020-12-03 22:36

    To accomplish your task you will need to use code. One solution, using more meaningful names, is as follows:

    Main table with two applicable columns:

    Table Name: Widgets

    Field 1: ID (Long)

    Field 2: Color (Text 32)

    Add table with two columns:

    Table Name: ColorListByWidget

    Field 1: ID (Long)

    Field 2: ColorList (Text 255)

    Add the following code to a module and call as needed to update the ColorListByWidget table:

    Public Sub GenerateColorList()
    
    Dim cn As New ADODB.Connection
    Dim Widgets As New ADODB.Recordset
    Dim ColorListByWidget As New ADODB.Recordset
    Dim ColorList As String
    
    Set cn = CurrentProject.Connection
    
    cn.Execute "DELETE * FROM ColorListByWidget"
    cn.Execute "INSERT INTO ColorListByWidget (ID) SELECT ID FROM Widgets GROUP BY ID"
    
    With ColorListByWidget
       .Open "ColorListByWidget", cn, adOpenForwardOnly, adLockOptimistic, adCmdTable
       If Not (.BOF And .EOF) Then
          .MoveFirst
          Do Until .EOF
             Widgets.Open "SELECT Color FROM Widgets WHERE ID = " & .Fields("ID"), cn
             If Not (.BOF And .EOF) Then
                Widgets.MoveFirst
                ColorList = ""
                Do Until Widgets.EOF
                   ColorList = ColorList & Widgets.Fields("Color").Value & ", "
                   Widgets.MoveNext
                Loop
             End If
             .Fields("ColorList") = Left$(ColorList, Len(ColorList) - 2)
             .MoveNext
             Widgets.Close
          Loop
       End If
    End With
    
    
    End Sub
    

    The ColorListByWidget Table now contains your desired information. Be careful that the list (colors in this example) does not exceed 255 characters.

    0 讨论(0)
  • 2020-12-03 22:36

    Well, you can use a Recordset object to loop through your query in VBA, concatenating field values based on whatever criteria you need.

    If you want to return the results as strings, you'll be fine. If you want to return them as a query, that will be more complicated. You might have to create a temporary table and store the results in there so you can return them as a table or query.

    0 讨论(0)
  • 2020-12-03 22:41

    You can concatenate the records with a User Defined Function (UDF).

    The code below can be pasted 'as is' into a standard module. The SQL for you example would be:

    SELECT tbl.A, Concatenate("SELECT B  FROM tbl
            WHERE A = " & [A]) AS ConcA
    FROM tbl
    GROUP BY tbl.A
    

    This code is by DHookom, Access MVP, and is taken from http://www.tek-tips.com/faqs.cfm?fid=4233

    Function Concatenate(pstrSQL As String, _
            Optional pstrDelim As String = ", ") _
                As String
        'example
        'tblFamily with FamID as numeric primary key
        'tblFamMem with FamID, FirstName, DOB,...
        'return a comma separated list of FirstNames
        'for a FamID
        '    John, Mary, Susan
        'in a Query
        '(This SQL statement assumes FamID is numeric)
        '===================================
        'SELECT FamID,
        'Concatenate("SELECT FirstName FROM tblFamMem
        '     WHERE FamID =" & [FamID]) as FirstNames
        'FROM tblFamily
        '===================================
        '
        'If the FamID is a string then the SQL would be
        '===================================
        'SELECT FamID,
        'Concatenate("SELECT FirstName FROM tblFamMem
        '     WHERE FamID =""" & [FamID] & """") as FirstNames
        'FROM tblFamily
        '===================================
    
        '======For DAO uncomment next 4 lines=======
        '======     comment out ADO below    =======
        'Dim db As DAO.Database
        'Dim rs As DAO.Recordset
        'Set db = CurrentDb
        'Set rs = db.OpenRecordset(pstrSQL)
    
        '======For ADO uncomment next two lines=====
        '======     comment out DAO above     ======
        Dim rs As New ADODB.Recordset
        rs.Open pstrSQL, CurrentProject.Connection, _
                adOpenKeyset, adLockOptimistic
        Dim strConcat As String 'build return string
        With rs
            If Not .EOF Then
                .MoveFirst
                Do While Not .EOF
                    strConcat = strConcat & _
                        .Fields(0) & pstrDelim
                    .MoveNext
                Loop
            End If
            .Close
        End With
        Set rs = Nothing
        '====== uncomment next line for DAO ========
        'Set db = Nothing
        If Len(strConcat) > 0 Then
            strConcat = Left(strConcat, _
                Len(strConcat) - Len(pstrDelim))
        End If
        Concatenate = strConcat
    End Function 
    
    0 讨论(0)
提交回复
热议问题