Есть ли в доступе MS (2003) что-либо, сопоставимое с хранимой процедурой. Я хочу выполнить сложный запрос в доступе к MS

У меня есть таблица, назовите ее TBL. Он имеет два столбца, назовите их A и B. Теперь в запросе мне нужен один столбец как A, а другой столбец должен быть разделенным запятыми списком всех B, которые против A в TBL. например TBL такой

1 Альфа

2 Бета

1 Гамма

1 Дельта

Результат запроса должен быть

1 Альфа, Гамма, Дельта

2 Бета

Такие вещи очень легко сделать с помощью курсоров в хранимой процедуре. Но я не могу сделать это через MS Access, потому что, по-видимому, он не поддерживает хранимые процедуры. Есть ли способ запустить хранимую процедуру в доступе MS? или есть ли способ через SQL выполнить этот тип запроса

Есть ли в VB6 хранимые процедуры? Есть ли в .NET хранимые процедуры? Access - это платформа для разработки приложений баз данных. Jet - это ядро ​​базы данных по умолчанию, о чем мы и хотели спросить. В Jet отсутствуют хранимые процедуры (нет серверного процесса, который бы ими управлял, поэтому не могло быть).

David-W-Fenton 24.10.2008 06:55
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
9
1
12 640
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Я не знаю способа запуска хранимых процедур в базе данных Access. Однако Access может выполнять хранимые процедуры, если он используется с серверной частью SQL. Если вы не можете разделить пользовательский интерфейс на Access и данные на SQL, то, вероятно, лучше всего будет закодировать модуль VBA, чтобы получить нужный результат.

Что ж, вы можете использовать объект Recordset для циклического выполнения вашего запроса в VBA, объединяя значения полей на основе любых критериев, которые вам нужны.

Если вы хотите вернуть результаты в виде строк, все будет в порядке. Если вы хотите вернуть их в виде запроса, это будет сложнее. Возможно, вам придется создать временную таблицу и сохранить в ней результаты, чтобы вы могли вернуть их в виде таблицы или запроса.

Ни хранимых процедур, ни временных таблиц.

Если вам нужно вернуть запрос в виде набора записей, вы можете использовать отключенный набор записей.

Ваш ответ кажется интересным, не могли бы вы объяснить его немного подробнее?

Varun Mahajan 23.10.2008 20:06

Отключенный набор записей - это устройство, используемое в Access обычно вместо временных таблиц, где вы создаете набор записей, а затем отменяете его ActiveConnection. Это сложно, но можно использовать там, где нужна временная таблица. Я недостаточно знаком, чтобы сообщить все подробности, вам нужно будет погуглить.

Lance Roberts 23.10.2008 22:30

Отключенный набор записей - это функция ADO, а не функция «Доступ». ADO не является предпочтительным интерфейсом для данных Jet - DAO. И вы можете получить те же функции «временной таблицы», используя транзакции и просто не фиксируя их.

David-W-Fenton 24.10.2008 06:56

ADO - это предпочтительный интерфейс мой для Jet :) Если вы думаете, что «временная таблица» приравнивается к транзакциям, вам тоже может понравиться ADO, потому что она, в отличие от DAO, поддерживает транзакции вложенный.

onedaywhen 24.10.2008 17:33

Я также использую ADO, хотя еще не изучил все тонкости.

Lance Roberts 24.10.2008 20:15

Я не сказал, что временные таблицы приравниваются к транзакциям, но вы можете получить такую ​​же производительность и функциональность, используя незафиксированные транзакции DAO, как и с отключенными наборами записей ADO. Конечно, это немного сложнее, но если вы работаете в среде, полностью состоящей из DAO, это предпочтительнее.

David-W-Fenton 05.02.2009 07:38

"использование незафиксированных транзакций DAO в качестве ... отключенных наборов записей ADO" - Хороший момент! Спасибо за разъяснения. P.S. отключенные наборы записей ADO могут быть созданы с нуля и могут быть иерархическими, поэтому лучше использовать их в качестве контейнеров общего назначения, но я понимаю, что все настройки DAO.

onedaywhen 05.02.2009 12:46

Я пил кулэйд ADO, когда он вышел, и просто не хотел использовать и DAO, и ADO. Многие приложения Access могут когда-нибудь дорасти до внешнего интерфейса SQL-сервера.

JeffO 19.02.2009 06:12

Я считаю, что вы можете создавать функции VBA и использовать их в своих запросах доступа. Это может вам помочь.

Для выполнения вашей задачи вам нужно будет использовать код. Одно из решений, использующее более значимые имена, заключается в следующем:

Основная таблица с двумя применимыми столбцами:

Table Name: Widgets

Field 1: ID (Long)

Field 2: Color (Text 32)

Добавьте таблицу с двумя столбцами:

Table Name: ColorListByWidget

Field 1: ID (Long)

Field 2: ColorList (Text 255)

Добавьте следующий код в модуль и вызовите по мере необходимости для обновления таблицы ColorListByWidget:

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

Таблица ColorListByWidget теперь содержит желаемую информацию. Будьте осторожны, чтобы список (цвета в этом примере) не превышал 255 символов.

Ответ принят как подходящий

Вы можете объединить записи с помощью пользовательской функции (UDF).

Приведенный ниже код можно вставить "как есть" в стандартный модуль. Пример SQL для вас:

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

Этот код принадлежит DHookom, Access MVP и взят из 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 

Вы спасли мой день и сделали мой день. Какое элегантное решение. Благодаря тонну

Varun Mahajan 24.10.2008 14:04

Вы можете использовать GetString в VBA, который вернет набор записей, разделенный любым значением, которое вам нравится (например, запятой, тире, ячейками таблицы и т. д.), Хотя я должен признать, что использовал его только в VBScript, а не в Visual Basic. У W3Schools есть хороший учебник, который, надеюсь, удовлетворит ваши потребности..

Вы можете написать свою хранимую процедуру в виде текста и отправить ее в базу данных с помощью:

Dim sp as string
sp = "your stored procedure here" (you can load it from a text file or a memo field?)

Access.CurrentProject.AccessConnection.Execute sp

Предполагается, что вы используете объекты ADODB (библиотека объектов данных ActiveX правильно упоминается в вашем приложении).

Я уверен, что с DAO есть что-то подобное ...

Возможно, вместо того, чтобы спрашивать, есть ли у Jet хранимые процедуры, вы должны объяснить, чего вы хотите достичь, а затем мы сможем объяснить, как это сделать с помощью Jet (неясно, используете ли вы Access для своего приложения или просто используете Jet MDB как ваше хранилище данных).

Если они пытаются сделать это в Access, я бы сказал «Использовать отчет». Если они пытаются сделать это в Jet (или любом другом SQL), я бы сказал: «Не делайте этого. Используйте отчет».

onedaywhen 24.10.2008 17:37

@Remou о функции Concatenate DHookom: ни в стандарте SQL, ни в Jet нет функции установки CONCATENATE(). Проще говоря, это потому, что это нарушение 1НФ. Я бы предпочел сделать это на стороне приложения, а не пытаться заставить SQL делать то, для чего он не предназначен. Возможно, многозначные типы ACE (Access2007) подходят лучше: все еще NFNF, но, по крайней мере, есть поддержка на уровне движка. Помните, вопрос относится к объекту хранится: как пользователь может запросить нескалярный столбец с помощью SQL ...?

@ Дэвид В. Фентон о том, есть ли в Jet хранимые процедуры: разве мы с вами не обсуждали это в группах новостей пару лет назад. Начиная с версии 4.0 Jet / ACE поддерживает следующий синтаксис в режиме запроса ANSI-92:

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

EXECUTE procedure [param1[, param2[, ...]];

Итак, Jet создает и выполняет то, что он знает (по крайней мере, в одном режиме) как «процедуру», которая «хранится» в файле MDB. Однако Jet / ACE SQL прост и понятен: он не имеет синтаксиса управления потоком, а PROCEDURE может содержать только один оператор SQL, поэтому о любом коде процессуальный не может быть и речи. Таким образом, ответ на вопрос, есть ли в Jet хранимые процедуры, является субъективным.

В данный момент у меня нет времени искать его, но разве «процедура» Jet 4 совсем не похожа на хранимые процедуры, которые предлагает большинство серверных баз данных? Другими словами, это что-то с очень ограниченной функциональностью, которое не может заменить объекты серверного типа?

David-W-Fenton 26.10.2008 01:38

Разве я уже не охватил все ваши вопросы? например Я сказал: «... это чисто и просто: в нем нет синтаксиса управления потоком, а ПРОЦЕДУРА может содержать только один оператор SQL, поэтому о каком-либо процедурном коде не может быть и речи», но вы все же хотите, чтобы я прояснил, это «что-то с очень ограниченной функциональностью»?

onedaywhen 28.10.2008 15:37

Другие вопросы по теме