Elixir项目中对':odbc.sql_query / 2'的调用中出现意外的':infinity'参数

时间:2018-07-16 12:12:00

标签: erlang odbc elixir

摘要

我正在尝试通过ODBC在Elixir中查询SQL数据库。

使用两个参数运行:odbc.sql_query/2时(请参见下面的代码示例),将出现第三个:infinity参数。第三个未知参数导致运行时异常:

C:\code\elixir_odbc>mix run
starting

13:44:37.212 [info]  Application elixir_odbc exited: exited in: MyMix.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (FunctionClauseError) no function clause matching in :odbc.sql_query/3
            (odbc) odbc.erl:186: :odbc.sql_query(#PID<0.101.0>, "select count(*) from 'my-catalog'.my_table", :infinity)
            (elixir_odbc) lib/elixir_odbc.ex:23: ElixirOdbc.get_rec_count/0
            (elixir_odbc) lib/my_mix.ex:7: MyMix.start/2
            (kernel) application_master.erl:273: :application_master.start_it_old/4
** (Mix) Could not start application elixir_odbc: exited in: MyMix.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (FunctionClauseError) no function clause matching in :odbc.sql_query/3
            (odbc) odbc.erl:186: :odbc.sql_query(#PID<0.101.0>, "select count(*) from 'my-catalog'.my_table", :infinity)
            (elixir_odbc) lib/elixir_odbc.ex:23: ElixirOdbc.get_rec_count/0
            (elixir_odbc) lib/my_mix.ex:7: MyMix.start/2
            (kernel) application_master.erl:273: :application_master.start_it_old/4

这个神秘的:infinity论点从哪里来?

详细信息

mix.exs中,我包括来自Erlang / OTP的:odbc

  def application do
    [
      mod: {MyMix, []},
      extra_applications: [:logger, :odbc]
    ]
  end

/lib/elixir_odbc.ex中,我有以下代码:

defmodule ElixirOdbc do
  def get_rec_count do
    :odbc.start()

    case :odbc.connect(
           'dsn=my_dsn',
           []
         ) do
      {:ok, conn} ->
        case :odbc.sql_query(conn, "select count(*) from 'my-catalog'.my_table") do
          {:selected, _colNames, [{count}]} -> IO.puts("Number of rows: #{count}")
          {:error, err} -> {:error, err}
        end

      {:error, err} ->
        {:error, err}
    end

    :odbc.stop()
  end
end

还在/lib/my_mix.ex中,我有以下mod,它实现了Application协议:

defmodule MyMix do
  use Application

  def start(_type, _args) do
    IO.puts("starting")

    ElixirOdbc.get_rec_count()

    Task.start(fn ->
      :timer.sleep(1000)
      IO.puts("done sleeping")
    end)
  end
end

应用程序编译时没有任何错误或警告。

使用ElixirOdbc.get_rec_count启动应用程序后,从iex REPL内部手动调用iex -S mix时,我遇到了同样的错误。

如果我直接从Erlang REPL(Eshell)手动运行odbc:sql_query/2,则一切正常,并且我从数据库中获得了预期的数据。

1 个答案:

答案 0 :(得分:0)

我找到了问题。

就我而言,有多个数据库目录,因此对:odbc.sql_query的调用就像这样:

:odbc.sql_query(conn, "select count(*) from 'my-catalog'.my_table")

请注意,第二个参数字符串是双引号,其中数据库目录名称('my-catalog')是单引号。这就是造成此问题的原因。

显然,嵌套引号需要相反。

将呼叫更改为此:

:odbc.sql_query(conn, 'select count(*) from "my-catalog".my_table')

一切正常:

c:\code\elixir_odbc>mix run
starting
Number of rows: 70737

14:41:49.304 [info]  Application odbc exited: :stopped

通过查看Eshell的历史记录并仔细查看了我进行的手动调用(正在运行),我发现了造成此问题的原因,并且发现我将报价单颠倒了。