如何修复包含多行错误的结果
Posted
技术标签:
【中文标题】如何修复包含多行错误的结果【英文标题】:How to fix the result consisted of more than one row error 【发布时间】:2017-03-14 05:49:53 【问题描述】:我在 mysql 中编写了如下所示的存储过程(它可以工作):
DELIMITER //
CREATE PROCEDURE getBrandRows(
IN pBrand VARCHAR(30),
OUT pName VARCHAR(150),
OUT pType VARCHAR(200),
OUT pRetailPrice FLOAT)
BEGIN
SELECT p_name, p_type, p_retailprice INTO pName, pType, pRetailPrice
FROM part
WHERE p_brand LIKE pBrand;
END//
DELIMITER ;
我尝试返回多个结果并显示它们。我已经尝试过 Stack 和 Internet 上描述的许多方法,但这对我没有帮助。我已经编辑了我的整个代码并创建了一个简单的代码,所以你们可以粘贴并编译它。它应该可以工作,但有错误。代码如下:
package javamysqlstoredprocedures;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class JavaMySqlStoredProcedures
private final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private final String DB_URL = "jdbc:mysql://anton869.linuxpl.eu:3306/"
+ "anton869_cars?noAccessToProcedureBodies=true";
private final String DB_USER = "xxx";
private final String DB_PASSWORD = "xxx";
class CallStoredProcedureAndSaveXmlFile extends SwingWorker<Void, Void>
@Override
public Void doInBackground()
displaySql();
return null;
@Override
public void done()
private void displaySql()
try
System.out.println("Connecting to MySQL database...");
Class.forName(DEFAULT_DRIVER);
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER,
DB_PASSWORD))
System.out.println("Connected to MySQL database");
CallableStatement cs = conn.prepareCall("CALL getBrandRows("
+ "?, ?, ?, ?)");
cs.setString(1, "Brand#13");
cs.registerOutParameter(2, Types.VARCHAR);
cs.registerOutParameter(3, Types.VARCHAR);
cs.registerOutParameter(4, Types.FLOAT);
boolean results = cs.execute();
while (results)
ResultSet rs = cs.getResultSet();
while (rs.next())
System.out.println("p_name=" + rs.getString("p_name"));
System.out.println("p_type=" + rs.getString("p_type"));
System.out.println("p_retailprice=" + rs
.getFloat("p_retailprice"));
rs.close();
results = cs.getMoreResults();
cs.close();
catch (SQLException e)
e.printStackTrace();
catch (ClassNotFoundException e)
e.printStackTrace();
public JavaMySqlStoredProcedures()
new CallStoredProcedureAndSaveXmlFile().execute();
public static void main(String[] args)
JavaMySqlStoredProcedures jmssp = new JavaMySqlStoredProcedures();
【问题讨论】:
Result consisted of more than one row
...我认为问题在于存储过程中的查询返回了多个记录。你需要解决这个问题。我的快速解决方法是在查询末尾添加LIMIT 1
,尽管逻辑上可能不正确。但是根据健全的业务逻辑,你最好添加限制为一条记录的逻辑。
如何使用procedure.返回并操作多条记录。我第一次这样做。我的意思是我想从过程中获取多条记录,并像使用游标一样查看每一行。
如果你能清楚地表达你想对多条记录做什么,那么也许有人可以帮助你。
我的任务是在某些条件下使用存储过程从表中获取一些列。以为我可以使用多个输出从程序中获得多个结果。我只想使用存储过程获得与使用 SELECT 语句选择 3 列相同的效果。
你的问题不是你选择了多少列,而是你选择了多少行。具体来说,您选择的是多行,并且您无法在已定义的存储过程中执行此操作。
【参考方案1】:
ResultSet 可以处理多条记录。我在您的代码中发现了一些错误。请尝试以下步骤
将你的 all close 方法移动到 finally 块。
try
//do something
catch (Exception e)
//do something
finally
try
resultSet.close();
statement.close();
connection.close();
catch (SQLException se)
//do something
您可以将结果放入列表中。查看示例
List<YourObject> list = new ArrayList<YourObject>();
while (rs.next())
YourObject obj = new Your Object();
obj.setName(rs.getString("p_name"));
obj.setType(rs.getString("p_type"));
obj.setRetailPrice(rs.getFloat("p_retailprice"));
list.add(obj);
确保您的查询正确且数据库连接正常。
【讨论】:
您的解决方案帮助我解决了我的问题。谢谢!【参考方案2】:如果您只是想显示结果,请不要使用 IN 或 OUT 参数。此外,您还应该借助 CONCAT 函数在 LIKE 子句中添加 '%%'。请试试这个:
DELIMITER //
CREATE PROCEDURE getBrandRows(
pBrand VARCHAR(30)
)
BEGIN
SELECT p_name, p_type, p_retailprice INTO pName, pType, pRetailPrice
FROM part
WHERE p_brand LIKE CONCAT("%", pBrand, "%");
END//
DELIMITER ;
【讨论】:
所以我所要做的就是删除输出并在过程中简单地使用 SELECT ? 对于这种情况,是的。但是,如果您想从主体内部获取标量结果或聚合结果,如 SUM()、COUNT() 或类似结果,则可以使用 OUT 参数指定其返回值。 请看这个dev.mysql.com/doc/refman/5.7/en/create-procedure.html【参考方案3】:我正在向所有有类似问题的人发布正确的解决方案:
1.更正的存储过程:
DELIMITER //
CREATE PROCEDURE getBrandRows(
IN pBrand VARCHAR(30))
BEGIN
SELECT p_name, p_type, p_retailprice
FROM part
WHERE p_brand = pBrand;
END//
DELIMITER ;
2。更正的 Java 代码:
package javamysqlstoredprocedures;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class JavaMySqlStoredProcedures
private final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private final String DB_URL = "jdbc:mysql://anton869.linuxpl.eu:3306/"
+ "anton869_cars?noAccessToProcedureBodies=true";
private final String DB_USER = "xxx";
private final String DB_PASSWORD = "xxx";
class CallStoredProcedureAndSaveXmlFile extends SwingWorker<Void, Void>
@Override
public Void doInBackground()
displaySql();
return null;
@Override
public void done()
private void displaySql()
Connection conn = null;
CallableStatement cs = null;
ResultSet rs = null;
try
System.out.println("Connecting to MySQL database...");
Class.forName(DEFAULT_DRIVER);
conn = DriverManager.getConnection(DB_URL, DB_USER,
DB_PASSWORD);
System.out.println("Connected to MySQL database");
cs = conn.prepareCall("CALL getBrandRows(?)");
cs.setString(1, "Brand#13");
boolean results = cs.execute();
while (results)
rs = cs.getResultSet();
while (rs.next())
System.out.println("p_name=" + rs.getString("p_name"));
System.out.println("p_type=" + rs.getString("p_type"));
System.out.println("p_retailprice=" + rs.getFloat(
"p_retailprice"));
results = cs.getMoreResults();
catch (SQLException | ClassNotFoundException e)
finally
try
if (rs != null ) rs.close();
if (cs != null) cs.close();
if (conn != null) conn.close();
catch (SQLException e)
public JavaMySqlStoredProcedures()
new CallStoredProcedureAndSaveXmlFile().execute();
public static void main(String[] args)
JavaMySqlStoredProcedures jmssp = new JavaMySqlStoredProcedures();
【讨论】:
【参考方案4】:您的存储过程返回多行。只需在存储过程中正确选择查询背后的逻辑,它就应该只返回一行。
here how to return multiple value
【讨论】:
但是如何使用返回多个数据集的存储过程对多条记录进行操作呢?以上是关于如何修复包含多行错误的结果的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 WPF 错误:“程序不包含适合入口点的静态 'Main' 方法”?
如何修复Facebook SDK“不包含bitcode”错误?
如何修复 Firebase 9.0 导入错误? “尝试导入错误:‘firebase/app’不包含默认导出(导入为‘firebase’)。”