使用 Groovy 脚本执行 SQL 查询

Execute SQL query using Groovy script

我正在尝试 运行 SQL 使用 Groovy 脚本更新查询。

//Global Properties Value
def dbServer = context.expand('${#Project#DB_Server}')
def dbPort = context.expand('${#Project#DB_Port}')
def dbName = context.expand('${#Project#DB_Name}')
def dbUser = context.expand('${#Project#DB_Username}')
def dbPass = context.expand('${#Project#DB_Password}')
def userID = context.expand('${#Project#userID}').toInteger()

//Convert HEX to Integer
def userSerialHex = context.expand('${#Project#userSerial}').toString();
BigInteger userSerialInteger = Long.parseLong(userSerialHex, 16);

log.info userSerialHex
log.info userID
log.info userSerialInteger

//Connection String
def con = Sql.newInstance("jdbc:sqlserver://$dbServer:$dbPort;" + "databaseName=" + dbName, dbUser, dbPass, 'com.microsoft.sqlserver.jdbc.SQLServerDriver')

//SQL Query
con.execute("update tblUserCardDetail set active=0 where fkUserID = $userID and cardValue = $userSerialInteger");

结果:

Fri Dec 08 20:24:25 IST 2017:INFO:182A11A53C68BD3C
Fri Dec 08 20:24:25 IST 2017:INFO:12901
Fri Dec 08 20:24:25 IST 2017:INFO:1741223607312891196

预期:它应该 return 为真并更新该行。

我得到的错误:

com.microsoft.sqlserver.jdbc.SQLServerException: The conversion from UNKNOWN to UNKNOWN is unsupported. error at line: 27

当我 运行 来自 sql 服务器的查询时,它更新成功。

update tblUserCardDetail set active=0 where fkUserID=12901 and cardValue=1741223607312891196

我认为您需要将 BigInteger userSerialInteger 显式转换为 String。

类似于:

con.execute("update tblUserCardDetail set active=0 where fkUserID = $userID and cardValue = ${userSerialInteger.toString()}");

来自groovy.sql.Sql#execute(groovy.lang.GString)

的源代码
    List<Object> params = getParameters(gstring);
    String sql = asSql(gstring, params);
    return execute(sql, params);

gstring的params传给execute不做任何处理

此类错误来自 SQL 驱动程序试图告诉您它不知道如何转换您作为参数传递的值。

您可以尝试将 def userID 更改为 int userID 或按如下方式转换参数。

即使 groovy.sql 足够聪明可以更改它,我也建议您使用带参数的方法更新语句(例如 groovy.sql.Sql.executeUpdate(String, List)):

con.executeUpdate('update tblUserCardDetail set active=0 where fkUserID = ? and cardValue = ?', [userID.toInteger(), userSerialInteger])

编辑:正如@a​​ristotll 所指出的,execute(GString) 并不那么聪明。这加强了我上面的建议,因为转换为文本不是一个很好的做法。但是,如果您使用的是 Microsoft JDBC 驱动程序,您还需要确保双方都使用了正确的类型,如 here 所述。

在 SoapUI 中使用 Groovy Script 使用 sql 连接时需要注意的几件事。

  1. 复制SOAPUI_HOME/bin/ext目录下的驱动库,重启工具
  2. 先用驱动class名称注册驱动。例如,mysql 服务器

    com.eviware.soapui.support.GroovyUtils.registerJdbcDriver("com.mysql.jdbc.Driver")

  3. 现在使用您的连接并执行查询。

针对您的问题,您可以使用 jTDC 驱动程序并将 jar 文件复制到上述位置。

获取连接的脚本:

def DRIVER_CLASS='net.sourceforge.jtds.jdbc.Driver'
def CONNECTION_STRING="jdbc:jtds:sqlserver://${databaseServer}:${databasePort}/${databaseName};domain=${domain}" as String
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver(DRIVER_CLASS)
def sql = Sql.newInstance(CONNECTION_STRING, DRIVER_CLASS)

现在您应该可以使用 sql.execute(..).

执行查询了

请注意,上面的连接字符串使用的是占位符值,只需使用正确的变量或使用实际值即可。

当我以其他方式更改 SQL 连接时,它以某种方式工作,这次我参数化了整个连接,包括 jdbc 驱动程序:

import groovy.sql.Sql
def dbString = context.expand('${#Project#DB_String}')
def dbDriver = context.expand('${#Project#DB_Driver}')
def dbUser = context.expand('${#Project#DB_Username}')
def dbPass = context.expand('${#Project#DB_Password}')
def con = Sql.newInstance(dbString, dbUser, dbPass, dbDriver)

//SQL Query
con.execute("update tblUserCardDetail set active=0 where fkUserID = $userID and cardValue = '$userSerialInteger'");