golang/sqlserver positional parameters in select statements

huangapple go评论97阅读模式
英文:

golang/sqlserver positional parameters in select statements

问题

有人能提供一个使用golang sqlserver驱动程序的Query或QueryRow(而不是QueryContext)的工作示例吗?该示例应包含一个简单的select语句和2个(或更多)位置参数。

似乎有一些变动:https://github.com/denisenkom/go-mssqldb/issues/260

唯一给出的示例代码是使用QueryContext的,对于一个简单的命令行数据转换程序来说,这太复杂了。在使用PostgreSQL或MySQL时,这非常简单,但是在使用SQL Server时,我遇到了困难。

使用以下代码:

var checkQuery = "select SigCode from @LRU where LRUEmu=@ENVVAR"
...
rows, err := db.Query(checkQuery, sql.Named("LRU", string1), sql.Named("ENVVAR", string2))

会产生以下错误:

application() rows.Query() failed:mssql: Must declare the table variable "@LRU".

编辑:根据下面的@Flimzy的建议,尝试使用QueryContext:

rows, err := db.QueryContext(context.TODO(), checkQuery,sql.Named("LRU", string1), sql.Named("ENVVAR", string2))

仍然是同样的错误。

@MWillemse:这里是一些示例代码(pymssql),它使用一个变量来指定目标表:

slice_cursor.execute(
    "select distinct Subsystem, Field from [%(dlog)s] "
    "where Subsystem not like 'STRING1' "
    "order by Subsystem, Field"
    % {
        'dlog' : datelog
    }
)

我经常这样做。在golang/pg中也是如此,非常顺利。

@putu:我尝试了你的建议,但没有成功。不过出现了新的错误...

var checkQuery = "DECLARE @LRU VARCHAR(255), @ENVVAR VARCHAR(255); select SigCode from @LRU where LRUEmu=@ENVVAR;"

// ...

rows, err := db.Query(checkQuery, sql.Named("LRU", string1), sql.Named("ENVVAR", string2))

会产生以下错误:

mssql: The variable name '@LRU' has already been declared. Variable names must be unique within a query batch or stored procedure.

英文:

Can anyone provide a working example of a Query or QueryRow (not QueryContext) with a simple select and 2 (or more) positional parameters using the golang sqlserver driver?

There's some churn, apparently: https://github.com/denisenkom/go-mssqldb/issues/260

The only sample code given is for QueryContext which is hypercomplex for a simple cli data transition program. This is brain-dead simple with postgres or mysql but I'm dead in the water with sql server.

Using:

var checkQuery = "select SigCode from @LRU where LRUEmu=@ENVVAR"
...
rows, err := db.Query(checkQuery, sql.Named("LRU", string1), sql.Named("ENVVAR", string2))

yields:

application() rows.Query() failed:mssql: Must declare the table variable "@LRU".

Edit. Per @Flimzy below, retried with QueryContext:

rows, err := db.QueryContext(context.TODO(), checkQuery,sql.Named("LRU", string1), sql.Named("ENVVAR", string2))

Same error.

@MWillemse: Here is some sample code (pymssql) which uses a variable to specify the target table:

slice_cursor.execute(
    "select distinct Subsystem, Field from [%(dlog)s] "
    "where Subsystem not like 'STRING1' "
    "order by Subsystem, Field"
    % {
        'dlog' : datelog
    }
)

I do it all the time. In golang/pg as well, works like a charm.

@putu: I tried your suggestion but no joy. New error, though...

var checkQuery = "DECLARE @LRU VARCHAR(255), @ENVVAR VARCHAR(255); select SigCode from @LRU where LRUEmu=@ENVVAR;"

// ...

rows, err := db.Query(checkQuery, sql.Named("LRU", string1), sql.Named("ENVVAR", string2))

Yields:

mssql: The variable name '@LRU' has already been declared. Variable names must be unique within a query batch or stored procedure.

答案1

得分: 1

我不懂Go语言,但我了解SQL Server。

以下是这些代码的翻译结果,并发送到SQL Server。生成的SQL代码可能如下所示:

DECLARE @LRU   NVARCHAR(MAX) = '<string1的内容>';
DECLARE @ENVAR NVARCHAR(MAX) = '<string2的内容>';
SELECT SigCode FROM @LRU WHERE LRUEmu = @ENVVAR;

当执行这段代码时,SQL Server会报错:

必须声明表变量 "@LRU"。

这个错误被QueryContext捕获并重新抛出。

SQL Server之所以报错,是因为查询中存在语法错误。SQL Server(以及其他关系型数据库管理系统)不允许将表名放在变量中,并对其进行查询。

所以你可以这样修改代码:

var checkQuery = "SELECT SigCode FROM " + string1 + " WHERE LRUEmu = @ENVVAR";
rows, err := db.Query(checkQuery, sql.Named("ENVVAR", string2));

或者使用动态SQL,像这样:

var checkQuery = 
    "DECLARE @SQL NVARCHAR(MAX) = 'SELECT SigCode FROM '+@LRU+' WHERE LRUEmu=@ENVVAR';" +
    "EXEC(@SQL);";
rows, err := db.Query(checkQuery, sql.Named("LRU", string1), sql.Named("ENVVAR", string2));
英文:

I don't know golang but i do know sql server.

var checkQuery = &quot;select SigCode from @LRU where LRUEmu=@ENVVAR&quot;
rows, err := db.Query(checkQuery, sql.Named(&quot;LRU&quot;, string1), sql.Named(&quot;ENVVAR&quot;, string2))

These lines must be getting translated into SQL code and send to SQL server. The resulting SQL code probably looks something like this:

DECLARE @LRU   NVARCHAR(MAX) = &#39;&lt;contents of string 1&gt;&#39;;
DECLARE @ENVAR NVARCHAR(MAX) = &#39;&lt;contents of string 2&gt;&#39;;
select SigCode from @LRU where LRUEmu=@ENVVAR

When this is executed SQL Server will raise the error

Must declare the table variable &quot;@LRU&quot;

Which is caught and rethrown by your QueryContext.

The reason for SQL server to raise the error is an syntax error in the query. SQL server does not (and afaik neither do other rdbms) allow you to put table names in a variable and run a select against it.

So you either to this:

var checkQuery = &quot;select SigCode from &quot; + string1 + &quot; where LRUEmu=@ENVVAR&quot;
rows, err := db.Query(checkQuery, sql.Named(&quot;ENVVAR&quot;, string2))

or use dynamic sql like this:

var checkQuery = 
       &quot;DECLARE @SQL NVARCHAR(MAX) = 
           &#39;select SigCode from &#39;+@LRU+&#39; where LRUEmu=@ENVVAR&#39;;
        EXEC(@SQL);&quot;
rows, err := db.Query(checkQuery, sql.Named(&quot;LRU&quot;, string1), sql.Named(&quot;ENVVAR&quot;, string2))

huangapple
  • 本文由 发表于 2017年8月2日 02:27:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/45445205.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定