【问题标题】:Undefined function 'Replace' in expression , Replace alternative?表达式中未定义的函数“替换”,替换替代?
【发布时间】:2014-09-14 12:48:20
【问题描述】:

正如在这个问题中读到的:Undefined function 'Replace' in expression,我收到错误“表达式中的未定义函数'替换'”,因为“您根本没有使用 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(" ", "");

【问题讨论】:

  • 请编辑您的问题并显示您收到错误的命令。
  • 删除空格和替换空格是有区别的!因此,如果您想在值的开头和结尾删除空格,您可以在 c# 中通过 trim() 执行此操作。另请注意,即使您可以执行大多数操作,也不会为字符串操作构建 sql
  • @WiiMaxx 我不仅想在结尾或开头删除它们,而是全部删除它们,我相信这样做的唯一方法是将“”替换为“”,即基本等于去掉空格

标签: c# sql ms-access oledbcommand


【解决方案1】:

根据我的经验,我认为 Gord Thompson 的回答是正确的。我安装了 Microsoft Access Database Engine 2007(只有 32 位版本)和 64 位 Microsoft Access Database Engine 2010 Redistributable。当我以 32 位发布我的 .net Click Once App 时,我遇到了错误,当我以 64 位发布时,事情进展顺利。 我进一步尝试,卸载了 Microsoft Access Database Engine 2007(只有 32 位版本)和 64 位的 Microsoft Access Database Engine 2010 Redistributable,安装了 32 位 Microsoft访问 Database Engine 2010 Redistributable,然后再次以 32 位发布我的应用程序,一切正常。

【讨论】:

    【解决方案2】:

    我在使用 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()
    

    我希望这会有所帮助。

    问候

    【讨论】:

      【解决方案3】:

      如果你下载并安装了

      Microsoft Access Database Engine 2010 Redistributable

      那么您可以在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();
      }
      

      请注意,您需要下载并安装与 .NET 应用程序具有相同“位数”的 Access 数据库引擎版本:32 位应用程序需要 32 位版本的数据库引擎,而 64 位应用程序需要数据库引擎的 64 位版本。

      【讨论】:

      • 请注意,Access 2016/2019 引擎 (Microsoft.ACE.OLEDB.16.0) 不支持 JET 3.0 数据库(Access 97 及更早版本),而且令人讨厌的是,ACE 16 驱动程序也将自身安装为 ACE 的别名12 驱动程序,因为即使 ACE 12 支持 JET 3.0 数据库,仍有许多程序将 Microsoft.ACE.OLEDB.12.0 硬编码到它们的连接字符串中。嗯。 (出于同样的原因,Office 2013 中不可再分发的 ACE 15 驱动程序也取代了 ACE 12)。
      【解决方案4】:

      我最后只在我的另一个答案中评论了它:不幸的是,我的 VBA 代码不适用于 OleDbCommand,但这不是适合您的解决方案吗:

      1. 我猜他们也有同样的问题,请参阅:Stackoverflow: Exception when trying to execute “REPLACE” against MS Access => 他们使用 INSTR / MID 解决了这个问题...也许这可以帮助您?

      2. 还有一个额外的解决方案:见:Codeguru: Replace doesnt work...

      这对你有帮助吗?

      问候

      阿德尔福斯

      【讨论】:

      • 这两个都是更新查询,我正在尝试使它们适用于我的选择查询,但我还没有弄清楚,当我这样做时会尝试更新你
      【解决方案5】:

      如果您可以将 VBA 代码放入 Access 模块中,则可以在 Access VBA 中使用此代码将字符串替换为其他字符串,而不是使用 buliltin Access 函数替换

      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 + '%'";
      

      您好,

      阿德尔福斯

      【讨论】:

      • 我不知道在哪里使用它,我想在我的 c# 项目中这样做
      • 如果您有可能更改 Access DB,您可以添加一个模块并将上述代码放入其中。在上面的 Gordon Linoffs 答案中,您应该写: \" \", \"\" 而不是:" ","" => 你需要转义 " 然后它应该编译
      • 我没有这种可能性(在大约 300 台计算机上运行),我会试试的
      • 你能编译它并出现同样的错误信息吗?
      • 我猜在旧版本的 VB/VBA 中没有内置函数 Replace。请参阅:vbarchiv.net/commands/cmd_replace.html - 如果没有额外的模块,我不知道如何解决这个问题。对不起。
      【解决方案6】:

      我怀疑问题在于您使用的是 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 功能,但可能因为引号问题而无法识别。

      【讨论】:

      • 如果我使用双引号则不编译(我不能用单外引号定义字符串)
      • 如果我转义引号也不会解决任何问题
      • 我对您的回答投了反对票,因为它应该被删除,原因如下。 1) OP 发布了 ANSI-92 查询模式语法(或者,没有发布 ANSI-89 查询模式),这说明了很多关于 ANSI-92 查询模式的信息。 2)您怀疑 OP 正在使用 SQL Server 是错误的。 OP 几乎可以肯定使用 .NET Framework 中的OleDbCommand,它总是 使用 ANSI-92 查询语法。您未能识别 ANSI-92 查询模式语法并将其误认为是来自另一个 DBMS 的语法...
      • 3) 您发布了 ANSI-89 查询模式语法。即使 OP 想要,OleDbCommand 也不能使用 ANSI-89 查询语法。 4) 您继续使用REPLACE 功能,该功能不适用于OleDbCommand 对象。这是问题的症结所在:OleDbCommand 不能使用REPLACE 函数。虽然 REPLACE 可以在 Access 用户界面(任一查询模式)中使用,但您不能在 Access UI 中使用 .NET Framework。 5)您对引号问题的暗示是错误的。 OP的问题与引号无关......
      • 总之,您误解了 ANSI-92 查询模式的使用,发布了 OP 无法使用的语法,没有意识到 OP 无法使用 REPLACE,有关 ANSI-92 的错误信息持续存在查询模式在某种程度上与 SQL Server 相关,并且无缘无故地提到了引号问题。那么告诉我,你认为答案的哪一部分值得保留?
      猜你喜欢
      • 2011-09-14
      • 2015-06-25
      • 2014-06-01
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多