Неопределенная функция «Заменить» в выражении, заменить альтернативу?

как написано в этом вопросе: Неопределенная функция "Заменить" в выражении, я получаю ошибка «Неопределенная функция« Заменить »в выражении», потому что «вы вообще не используете механизм запросов Access», но что мне использовать в качестве альтернативы? По-видимому, «комбинация Iif, Instr» будет работать, но я не могу найти способ заменить что-то этим.

Все, что я хочу, это удалить пробелы из значения, как мне это сделать?

const string strSql = "SELECT TOP 15 HOOFDGROEP.HOOFDGROEP, SUBGROEP.SUBGROEP, Artikels.*" +
                                  " FROM (Artikels LEFT JOIN HOOFDGROEP ON Artikels.HOOFDGROEPID = HOOFDGROEP.ID)" +
                                  " LEFT JOIN SUBGROEP ON Artikels.SUBGROEPID = SUBGROEP.ID WHERE REPLACE(ArtikelNaam, ' ', '') LIKE  '%' + @ArtikelNaam + '%'";

            var objCommand = new OleDbCommand(strSql, _objConnection);
            objCommand.Parameters.Add("@ArtikelNaam", OleDbType.Char).Value = naamZoeker.Replace(" ", "");

person Boyen    schedule 23.07.2014    source источник
comment
Пожалуйста, отредактируйте свой вопрос и покажите команду, в которой вы получаете ошибку.   -  person Gordon Linoff    schedule 23.07.2014
comment
Существует разница между удалением пробелов и их заменой! Поэтому, если вы хотите удалить пробелы в начале и в конце вашего значения, вы можете сделать это в С# с помощью функции trim(). Также обратите внимание, что sql не предназначен для строковых операций, даже если вы можете выполнять большинство из них.   -  person WiiMaxx    schedule 23.07.2014
comment
@WiiMaxx Я хочу удалить их не только в конце или начале, но и все, и я считаю, что единственный способ сделать это — заменить на , что в основном равносильно удалению пробелов   -  person Boyen    schedule 23.07.2014


Ответы (6)


Если вы скачаете и установите

Распространяемый компонент Microsoft Access Database Engine 2010

то вы можете использовать следующее в строке подключения для вашего объекта OleDbConnection...

Provider=Microsoft.ACE.OLEDB.12.0

...и функция Replace() будет доступна для ваших запросов. Например, у меня работает следующий код:

using (var conn = new OleDbConnection())
{
    conn.ConnectionString =
            @"Provider=Microsoft.ACE.OLEDB.12.0;" +
            @"Data Source=C:\__tmp\testData.accdb;";
    conn.Open();
    using (var cmd = new OleDbCommand())
    {
        cmd.Connection = conn;
        cmd.CommandText =
            "UPDATE Table1 SET ProductType = Replace(ProductType, ' ', '')";
        cmd.ExecuteNonQuery();
    }
    conn.Close();
}

Обратите внимание, что вам необходимо загрузить и установить версию ядра базы данных Access с той же «разрядностью», что и ваше приложение .NET: для 32-разрядных приложений требуется 32-разрядная версия ядра базы данных, а для 64-разрядных приложений требуется 64-разрядная версия ядра базы данных. разрядная версия движка базы данных.

person Gord Thompson    schedule 24.07.2014
comment
Обратите внимание, что Access 2016/2019 Engine (Microsoft.ACE.OLEDB.16.0) не поддерживает базы данных JET 3.0 (Access 97 и более ранние версии), и, что раздражает, драйвер ACE 16 также устанавливается как псевдоним для драйвера ACE 12, потому что так много программ жестко закодировали Microsoft.ACE.OLEDB.12.0 в свои программы. строки подключения, хотя ACE 12 поддерживал базы данных JET 3.0. Гррр. (Нераспространяемый драйвер ACE 15 в Office 2013 также заменил ACE 12 по той же причине). - person Dai; 28.07.2020

У меня была такая же проблема с функцией REPLACE, однако я исправил ее, изменив соединение OleDb на соединение Odbc следующим образом:

Dim dbConn As New System.Data.Odbc.OdbcConnection
dbConn.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\db_name.accdb;Uid=Admin;Pwd=;"
dbConn.Open()

Dim objCmd As New System.Data.Odbc.OdbcCommand()
With objCmd
    .Connection = dbConn
    .CommandType = CommandType.Text
    .CommandText = "UPDATE table_name SET target_field = Replace(source_field, ' ', '') "
End With
objCmd.ExecuteNonQuery()

dbConn.Close()

Надеюсь, это поможет.

С Уважением

person Issac Peña    schedule 12.08.2015

Я прокомментировал это только наконец в своем другом ответе: мой код VBA, к сожалению, не работает с OleDbCommand, но разве это не решение для вас:

  1. Поскольку я предполагаю, что у них была такая же проблема, см.: Stackoverflow: Исключение при попытке выполнить «REPLACE» против MS Access => Они обошли это с помощью INSTR / MID... может быть, это могло бы вам помочь?

  2. И есть дополнительное решение: см.: Codeguru: замена не работает ...

Вам это помогает?

Привет

Адельфос

person Adelphos    schedule 23.07.2014
comment
Это оба запроса на обновление, я пытаюсь заставить их работать для моего запроса на выборку, но я еще не разобрался в этом, я постараюсь сообщить вам, когда я это сделаю - person Boyen; 23.07.2014

Я подозреваю, что проблема в том, что вы используете синтаксис SQL Server вместо синтаксиса MS Access. Я думаю, что это версия MS Access:

SELECT TOP 15 HOOFDGROEP.HOOFDGROEP, SUBGROEP.SUBGROEP, Artikels.*
FROM (Artikels LEFT JOIN
      HOOFDGROEP
      ON Artikels.HOOFDGROEPID = HOOFDGROEP.ID) LEFT JOIN
     SUBGROEP
     ON Artikels.SUBGROEPID = SUBGROEP.ID
WHERE REPLACE(ArtikelNaam, " ", "") LIKE  "*" & @ArtikelNaam & "*";

REPLACE() является функцией MS Access, но, возможно, не распознает ее из-за проблем с кавычками.

person Gordon Linoff    schedule 23.07.2014
comment
Не компилируется, если я использую двойные кавычки (я не могу определить строку с одинарными внешними кавычками) - person Boyen; 23.07.2014
comment
Ничего не исправляет, если я тоже избегаю кавычек - person Boyen; 23.07.2014
comment
@Бойен. . . Вы используете вы используете MS Access? - person Gordon Linoff; 23.07.2014
comment
Да, я использую MS 2007 Access. - person Boyen; 23.07.2014
comment
-1 они используют так называемый 'ANSI-92' Режим запроса синтаксис. - person onedaywhen; 07.08.2014
comment
@onedaywhen . . . Учитывая, что в вопросе ничего не говорится об использовании режима запросов ANSI-92, это не кажется причиной для понижения ответа. Вместо этого это был бы подходящий комментарий, чтобы спросить ОП. - person Gordon Linoff; 07.08.2014
comment
Я отклонил ваш ответ, потому что его следует удалить и по следующим причинам. 1) OP опубликовал синтаксис режима запросов ANSI-92 (в качестве альтернативы, не опубликовал режим запросов ANSI-89), и это многое говорит о режиме запросов ANSI-92. 2) Ваше подозрение, что OP использует SQL Server, неуместно. OP почти наверняка использует OleDbCommand из .NET Framework, который всегда использует синтаксис запроса ANSI-92. Вы не смогли распознать синтаксис режима запросов ANSI-92 и приняли его за синтаксис другой СУБД... - person onedaywhen; 13.08.2014
comment
3) Вы опубликовали синтаксис режима запросов ANSI-89. OleDbCommand не может использовать синтаксис запроса ANSI-89, даже если OP захочет. 4) Вы продолжили использовать функцию REPLACE, которая недоступна для объекта OleDbCommand. В этом суть проблемы: OleDbCommand не может использовать функцию REPLACE. Хотя REPLACE можно использовать в пользовательском интерфейсе Access (в любом режиме запросов), вы не можете использовать .NET Framework в пользовательском интерфейсе Access. 5) Ваш намек на проблему с кавычками неуместен. Проблема ОП не имеет ничего общего с кавычками... - person onedaywhen; 13.08.2014
comment
Таким образом, вы неправильно поняли использование режима запросов ANSI-92, опубликовали синтаксис, который OP не может использовать, не смогли понять, что REPLACE не может использоваться OP, увековечили дезинформацию о том, что режим запросов ANSI-92 каким-то образом связан с SQL Server и упоминается проблема с кавычками без видимой причины. Итак, скажите мне, какую часть вашего ответа вы считаете достойной сохранения? - person onedaywhen; 13.08.2014

Если вы можете поместить код VBA в модуль доступа, вы можете использовать этот код в Access VBA для замены строки другой строкой вместо использования встроенной функции доступа Replace:

Public Function TransformString(ByVal ToTransformStr As String, ByVal ReplaceStr As String, ByVal ToReplaceStr As String) As String
  Dim i As Long, sTmpString As String

  sTmpString = ""
  For i = 1 To Len(ToTransformStr)
    If Mid$(ToTransformStr, i, Len(ReplaceStr)) = ReplaceStr Then
      sTmpString = sTmpString & ToReplaceStr
      If Len(ReplaceStr) > 1 Then
        i = i + Len(ReplaceStr) - 1
      End If
    Else
      sTmpString = sTmpString & Mid$(ToTransformStr, i, 1)
    End If
  Next i

  TransformString = sTmpString

End Function

Протестируйте этот код с помощью:

Sub test()

Dim test As String

test = TransformString(" xyzABC ABCxyz ", " ", "")

End Sub

Это то же самое, что:

test = Replace(" xyzABC ABCxyz ", " ", "")

Результат в обоих случаях:

"xyzABCABCxyz"

И тогда это должно работать (с дополнительным экранированием "как \"):

const string strSql = "SELECT TOP 15 HOOFDGROEP.HOOFDGROEP, SUBGROEP.SUBGROEP, Artikels.*" +
                              " FROM (Artikels LEFT JOIN HOOFDGROEP ON Artikels.HOOFDGROEPID = HOOFDGROEP.ID)" +
                              " LEFT JOIN SUBGROEP ON Artikels.SUBGROEPID = SUBGROEP.ID WHERE TransformString(ArtikelNaam, \" \", \"\") LIKE  '%' + @ArtikelNaam + '%'";

Привет,

Адельфос

person Adelphos    schedule 23.07.2014
comment
Я понятия не имею, где его использовать, я хочу сделать это в своем проекте С#. - person Boyen; 23.07.2014
comment
Если у вас есть возможность изменить БД доступа, вы можете добавить модуль и поместить в него приведенный выше код. В ответе Гордона Линоффа выше вы должны написать: \ \, \\ вместо: , => вам нужно сбежать, тогда он должен скомпилироваться - person Adelphos; 23.07.2014
comment
У меня нет такой возможности (работает более чем на 300 компьютерах), и я попробую это сделать. - person Boyen; 23.07.2014
comment
Можете ли вы скомпилировать его, и появляется то же сообщение об ошибке? - person Adelphos; 23.07.2014
comment
Я предполагаю, что в более старых версиях VB/VBA нет встроенной функции Replace. См.: vbarchiv.net/commands/cmd_replace.html — я не знаю, как чтобы обойти это без дополнительного модуля. Прости. - person Adelphos; 23.07.2014
comment
с VB вы имеете в виду Visual Basic? потому что это код С# - person Boyen; 23.07.2014
comment
Вы используете C# OleDBCommand для вызова запроса к базе данных Access 2007. Я думаю, проблема в том, что невозможно использовать функцию доступа Replace в вашей строке strSql, потому что она говорит: вы вообще не используете механизм запросов Access. Сам Access 2007 поддерживает функцию VBA Replace — она достаточно новая. - person Adelphos; 23.07.2014
comment
Думаю, у них была та же проблема: выполнить замену против доступа ms"> stackoverflow.com/questions/4834536/ => Они обошли это с помощью уродливого INSTR/MID... может быть, это могло бы вам помочь? - person Adelphos; 23.07.2014
comment
И последнее, но не менее важное: есть дополнительное решение: forums.codeguru .com/ - person Adelphos; 23.07.2014

По моему опыту, я думаю, что ответ Горда Томпсона правильный. У меня был установлен Microsoft Access Database Engine 2007 (есть только 32-разрядная версия) и 64-разрядный распространяемый компонент Microsoft Access Database Engine 2010. Когда я опубликовал свое приложение .net Click Once в 32-битной версии, у меня возникла ошибка, когда я опубликовал ее в 64-битной версии, все прошло хорошо. Я попытался продолжить, удалил Microsoft Access Database Engine 2007 (есть только 32-разрядная версия) и 64-разрядный распространяемый компонент Microsoft Access Database Engine 2010, установил 32-разрядную версию Microsoft Получите доступ к Database Engine 2010 Redistributable, а затем снова опубликуйте мое приложение в 32-разрядной версии, все было в порядке.

person chphzz    schedule 22.02.2019