web-dev-qa-db-ja.com

MS Accessデータベース(2010)クエリデザイナから一時テーブル/プロシージャ/ビューを作成する方法

クエリデザイナを使用してMSAccessデータベース(2010)に一時テーブル/ビュー/ストアドプロシージャを作成する方法はありますか?

私がこのようなことを実行しようとするときはいつでも:

SELECT * INTO #temp_table
FROM (SELECT column_1, column_2 FROM table)

MSAccessはエラーをスローします:

CREATETABLEステートメントの構文エラー。

それ以上の情報はありません。

5
Kajiyama

Access SQLは、一度に複数のSQLステートメントの実行をサポートしていないため、#tempテーブルの概念は実際には適用されません。一時テーブルが必要な場合は、

  • 「実際の」テーブルを作成し、
  • それであなたの仕事をして、それから
  • 完了したら、テーブルを削除(削除)します。
7
Gord Thompson

私の知る限り、Access Query Designerで質問のようなSQLステートメントを実行する方法はありません。これは、すべてのステートメントがビュー/プロシージャまたは関数の定義であると想定しているためです。

あなたの声明には一般的な問題があります。 FROM句内で副選択/派生テーブルを使用する場合、返される結果にエイリアスを使用する必要があります。これはSQLServer ManagementStudioで機能します。

SELECT * INTO #temp_table
FROM (SELECT column_1, column_2 FROM table) AS someAlias

Access Data Project(ADP)アプリケーションを開発するときは、ほとんどのSQL作業にSQL Server Management Studio(または同様のツール)を使用することをお勧めします。

0
PhilS

これは、次を追加すると機能します。

SET NOCOUNT ON
SELECT * INTO #temp_table
FROM (SELECT column_1, column_2 FROM table)
0
nmjenny

これは1年間回答されていますが、次のアプローチが、私のように、MS Accessの欠点を実用的な方法で補おうとしていて、実際のSQLクエリに集中したい他の人に役立つことを願っています。

それはカバーします:

  • テキストファイルに格納された読みやすいSQLプロシージャを実行する(連結された文字列を使用してVBAでコーディングする一般的なソリューションは、すぐに不便で困難になります)

  • 「一時的な」テーブルを使用します。このソリューションは、accdbが「肥大化」するのを防ぐものではないことに注意してください。そのため、accdbを時々圧縮する必要があります。一時データベースでプロシージャを実行することを選択した場合、これを防ぐことができます。これには、追加のコーディングとエラー処理が必要です。

(次のコードをテンプレートとして使用して空のaccdbを使用し、そこから作業します。たとえば、追加のVBAルーチンまたはフォームが必要な場合などです。)

ステップ:

1-SQLステートメントまたはプロシージャ全体をtxtfileに保存します。 VBAコードを短くしようとすると、

  • セミコロンで閉じるSQLステートメント;改行が続く

  • コメント行は行全体にまたがります。つまり、/ *の前または* /の後に追加のインライン文字はありません。

OPobv。 sql-editorにアクセスできますが、他の人はアクセスできない場合があります。ただし、会社の環境でも、通常、SQLハイライトを使用してフリーウェアのテキストエディタを入手できるはずです(.sql-extensionsを含むファイルの構文を強調表示する notepad ++ など)。

2-ルーチンを呼び出す

Sub SubRunSQL()
On Error Resume Next
droptemptables
On Error GoTo 0

runSQL CurrentProject.path & "\_sql\p01.sql"

End Sub

3-「一時的な」テーブルを閉じる+削除する(私の場合、接頭辞「tmp」でラベル付けされている場合、bc Accessにはテーブル名の#文字に関する問題があります-つまり、テーブル名はSQLの[括弧]に入れる必要があります。これらのテーブルをループで削除すると問題が発生します)。

「resumenext」でラップするのはエレガントではありませんが、私の場合、最も堅牢なソリューションであることが証明されました(目標は、実際のSQLコードのコーディングであり、その周りのUIではありません)。

Sub droptemptables()
Dim tdf As TableDef
For Each tdf In CurrentDb.TableDefs
    If tdf.Name Like "tmp*" Then
        DoCmd.Close acTable, tdf.Name, acSaveNo
        DoCmd.DeleteObject acTable, tdf.Name
    End If
Next tdf
End Sub

4-SQLプロシージャをフェッチし、ループ内の単一のステートメントを処理します。

Sub runSQL(path As String)

Dim dbs As DAO.Database
Set dbs = CurrentDb

Dim sql As String
sql = fetchSQL(path)

' optional: replace some string in your textfile with a public declared variable (here: Public Const dwh As String = "'I:\mydwh.accdb'")
sql = Replace(sql, "#dwh", dwh)

' Split at semicolon + carriage left
Dim arrsql() As String
arrsql() = Split(sql, ";" & vbNewLine)

' Loop through the SQL-Statements
Dim i As Integer
For i = LBound(arrsql()) To UBound(arrsql())
    Debug.Print arrsql(i)
    dbs.Execute arrsql(i), dbFailOnError
Next i
End Sub

5-テキストファイルの内容を文字列として返すための標準関数。この場合、コメント行もスキップします。これは、SQLにコメントしないことを選択した場合は冗長です。

Function fetchSQL(path As String) As String

Dim skpLine As Boolean
Dim Line As String
Dim iFile As Integer
iFile = FreeFile
Open path For Input As #iFile

' skip commented lines /* ... */
Do Until EOF(iFile)
    Line Input #iFile, Line
    If Left(Line, 2) = "/*" Then skpLine = True
    If skpLine = False Then fetchSQL = fetchSQL & vbNewLine & Line
    If Right(Line, 2) = "*/" Then skpLine = False
Loop
Close #iFile
End Function
0
Martin Dreher