【问题标题】:prepared statements in luasql.postgresluasql.postgres 中的预处理语句
【发布时间】:2013-04-23 18:42:30
【问题描述】:

我正在尝试按照此处找到的在 luasql 中使用准备好的语句的示例进行操作: http://lists.luaforge.net/pipermail/kepler-project/2008-January/002207.html

我安装了 luasql 2.2.0 版。

当我尝试示例代码时,我收到以下错误消息:

lua: postgrestest.lua:63: 尝试调用方法 'gettypes' (a nil 值)堆栈回溯: postgrestest.lua:63: 在主块中 [C]:?

代码如下:

require "luasql.postgres"
local databasename = "test"
local databaseUser = "user"
local databasepassword = "password"
local databaseserver="10.10.10.10" -- only rqd for remote database servers.
--local databaseserver="127.0.0.1"
local databaseport = 5432 -- only rqd for remote database servers.

env = assert (luasql.postgres())
con = assert (env:connect(databasename, databaseUser, databasepassword, databaseserver))

-- DROP ANY EXISTING PEOPLE TABLE
-- note:  con:execute() Returns: a cursor object if there are results, or the number of rows affected by the command otherwise.
res = con:execute("DROP TABLE people")

-- RECREATE PEOPLE TABLE
res = assert (con:execute[[
    CREATE TABLE people(
        id integer,
        fname text,
        lname text,
        job text
    )
]])
print ('result from create table is:'..res)
-- ADD SOME PEOPLE TO THE PEOPLE TABLE
res = assert(con:execute("INSERT INTO people " ..
    "VALUES (1, 'Roberto', 'Ierusalimschy', 'Programmer')"), "record inserted")
print ("result from insert"..res)

res = assert(con:execute("INSERT INTO people " ..
    "VALUES (3, 'Taylor', 'Swift', 'Singer')"))

-- RETRIEVE THE PEOPLE TABLE SORTED BY LAST NAME INTO CURSOR
cur = assert (con:execute"SELECT * from people order by lname")

-- LOOP THROUGH THE CURSOR AND PRINT
print()
print(string.format("%15s  %-15s %-15s %-15s",
    "#", "FNAME", "LNAME", "JOB"))
print(string.format("%15s  %-15s %-15s %-15s",
    "-", "-----", "-----", "---"))
row = cur:fetch ({}, "a")
while row do
    print(string.format("%15d  %-15s %-15s %-15s",
        row.id, row.fname, row.lname, row.job))
    row = cur:fetch (row, "a")
end
print()

-- prepared statements 
types = con:gettypes()
stmt, err = con:prepare("select * from people where lname=$1", types["text"])
if err then
    print("problems creating prepared statement"..err)
else
    cur, err = stmt:execute("Swift")
  if err then
        print("Couldn't execute the statement: "..err);
    else
        results = cur:fetch({}, "a")
        while results do
            print(results.id)
        end
    end
end 
-- CLOSE EVERYTHING
cur:close()
con:close()
env:close()

我还尝试将准备语句更改为如下所示:

--types = con:gettypes()
--stmt, err = con:prepare("select * from people where lname=$1", types["text"])
stmt, err = con:prepare("select * from people where lname=$1", "Swift")
if err then
    print("problems creating prepared statement"..err)
else
    --cur, err = stmt:execute("Swift")
    cur, err = stmt:execute()
  if err then
        print("Couldn't execute the statement: "..err);

但是我得到了同样的错误信息,除了使用准备方法:

lua: postgrestest.lua:65: attempt to call method 'prepare' (a nil value)
stack traceback:
        postgrestest.lua:65: in main chunk
        [C]: ?

你能告诉我我做错了什么/如何解决这个问题吗?谢谢!

编辑 1

与数据库的连接和所有其他代码都可以正常工作。循环遍历表格并打印数据的代码有效。

谢谢。

【问题讨论】:

  • 您似乎没有建立连接。
  • 我正在建立连接,因为我添加的任何打印语句都可以显示我刚刚创建的表。我将更新我的帖子以包含该内容
  • 您确定您正确应用了补丁吗?在我看来,你在那期间失败了。
  • 是的...我认为该补丁已合并到最新版本的 luasql 中...但我想不是。

标签: postgresql lua prepared-statement


【解决方案1】:

如 cmets 中所述,您需要应用一个您显然没有的补丁。但是,如果您需要在支持它们的语言框架之外使用准备好的语句,您可以手动使用 PostgreSQL 的服务器端准备好的语句。

基本上,您在 SQL 中声明您的存储过程,然后在 SQL 中调用它,就像调用函数一样。准备好的语句有点像临时 SQL 语言函数。因此,通过任何 SQL 接口,您仍然可以执行以下操作:

PREPARE my_insert(int, int, text, text) AS
INSERT INTO foo(id, bar, baz, test)
values ($1, $2, $3, $4);

然后你可以重复调用它(使用相同的计划):

EXECUTE my_insert(1, 3, 'foo', 'bar');

即使您的客户端框架不支持它们,这也允许您执行此类准备好的语句。

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    相关资源
    最近更新 更多