简体   繁体   English

通过Arraylst <Arraylist<String> &gt;到使用JAVA的MSSQL存储过程?

[英]Pass Arraylst<Arraylist<String>> to MSSQL Stored procedure using JAVA?

Here I am trying to pass List to stored procedure but getting the following error: 在这里,我试图将List传递给存储过程,但收到以下错误:

Operand type clash: nvarchar is incompatible with UserType 操作数类型冲突:nvarchar与UserType不兼容

//Stored Procedure
ALTER PROCEDURE [dbo].[UserDetails]
(
                @OutId NVARCHAR(50) OUTPUT,
                @Type NVARCHAR(50) Type,
                ,@Preload UserType READONLY
)
AS

UserDefined datatype 用户定义的数据类型

CREATE TYPE [dbo].[UserType] AS TABLE(
                [Id] [int] NULL,
                [Name] [nvarchar](50) NULL,
                [Company] [nvarchar](100) NULL,
                [PNumber] [nvarchar](100) NULL,
                [FClass] [nvarchar](100) NULL,
)
GO

JAVA Class JAVA类

package Test;

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class TestPreload {

                public static void main(String[] args) {
                                // TODO Auto-generated method stub
                                ArrayList<ArrayList<String>> PreloadUser=new ArrayList<ArrayList<String>>();
                                ArrayList<String> Preload=new ArrayList<String>();

                                Preload.add("1");
                                Preload.add("Danny");
                                Preload.add("123");
                                Preload.add("123");
                                Preload.add("N/A");

                                PreloadUser.add(Preload);

                                ArrayList<String> Preload2=new ArrayList<String>();
                                Preload2.add("1");
                                Preload2.add("Sam");
                                Preload2.add("123");
                                Preload2.add("123");
                                Preload2.add("N/A");

                                PreloadUser.add(Preload2);

                                try {
                                                DriverManager
                                                                                .registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());
                                                Connection conn = DriverManager
                                                                                .getConnection("jdbc:sqlserver://....");
                                                CallableStatement stmt = conn
                                                                                .prepareCall("{call UserDetails(?,?,?)}");
                                                stmt.setString(2, "Test");
                                                stmt.setString(3, PreloadUser.toString());
                                                //stmt.setObject(3, PreloadUser.toString());

                                                stmt.registerOutParameter(1, java.sql.Types.VARCHAR);
                                                stmt.execute();
                                                System.out.println("OUTPUT : " + stmt.getString(1));
                                                                                                } catch (SQLException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                }

                }

}

Stack Trace: 堆栈跟踪:

com.microsoft.sqlserver.jdbc.SQLServerException: Operand type clash: nvarchar is incompatible with UserType at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196) at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:388) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:338) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4026) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416) at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:185) at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:160) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedState com.microsoft.sqlserver.jdbc.SQLServerException:操作数类型冲突:nvarchar与com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult的com.microsoft.sqlserver.jdbc.SQLServerServer.makeFromDatabaseError(SQLServerException.java:196)处的UserType不兼容(SQLServerStatement.java:1454)在com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:388)在com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement $ PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:338) com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416)上的microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4026)com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement) com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:160)上的com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedState上的java:185) ment.java:320) at carma.TestInsurence.main(TestPreload.java:71) ment.java:320)位于carma.TestInsurence.main(TestPreload.java:71)

You are doing {call UserDetails(?,?,?)} but your stored procedure do not take any argument. 您正在执行{call UserDetails(?,?,?)}但是您的存储过程不带任何参数。 You need to change your stored procedure as follows: 您需要按以下方式更改存储过程:

CREATE PROCEDURE dbo.sp_Students_INS_byPK
       @user_id                     INT                       , 
       @user_name                   NVARCHAR(50)      = NULL  , 
       @user_company                NVARCHAR(100)     = NULL  ,
       @user_pno                    NVARCHAR(100)     = NULL  ,
       @user_fclass                 NVARCHAR(100)     = NULL  ,
AS 
BEGIN 
     SET NOCOUNT ON 

     INSERT INTO dbo.Students
          ( 
            Id                            ,
            Name                          ,
            Company                       ,
            PNumber                       ,
            FClass                                  
          ) 
     VALUES 
          ( 
            @user_id                      ,
            @user_name                    ,
            @user_company                 ,
            @user_pno                     ,
            @user_fclass                                  
          ) 

END 

Change your code as follows: 更改您的代码,如下所示:

CallableStatement stmt = conn.prepareCall("{call UserDetails(?,?,?,?,?)}");
stmt.setInt(1, 1);
stmt.setString(2, "Sam");
stmt.setString(3, "123");
stmt.setString(4, "123");
stmt.setString(5, "N/A");
stmt.execute();

Moreover, I don't understand why you are inserting the data in your table by calling the stored procedure. 而且,我不明白为什么您要通过调用存储过程将数据插入表中。 You can simple use the PreparedStatement to do so. 您可以简单地使用PreparedStatement这样做。 Here is an example: 这是一个例子:

public static void main(String[] args) {
   Connection conn = null;
   PreparedStatement stmt = null;
   try{
      DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());
      conn = DriverManager.getConnection("jdbc:sqlserver://....");

      String sql = "INSERT INTO UserType("Id", "Name",
            "Company", "PNumber", "FClass") VALUES(?,?,?,?,?)";
      stmt = conn.prepareStatement(sql);

      stmt.setInt(1, 1);
      stmt.setString(2, "Sam");
      stmt.setString(3, "123");
      stmt.setString(4, "123");
      stmt.setString(5, "N/A");

      stmt.executeUpdate();

      stmt.close();
      conn.close();
   }catch(Exception ex){
      ex.printStackTrace();
   }finally{
      try{
         if(numm != stmt)
            stmt.close();
      }catch(SQLException se){
         se.printStackTrace();
      }
      try{
         if(null != conn)
            conn.close();
      }catch(SQLException se){
         se.printStackTrace();
      }
   }
}

If you are using Spring Framework then you can utilize JdbcTemplate to do it easily. 如果您使用的是Spring Framework,则可以利用JdbcTemplate轻松完成。 Here is an example: 这是一个例子:

SimpleJdbcInsert insertUser = new SimpleJdbcInsert(jdbcTemplate)
            .withTableName("UserType").usingColumns("Id", "Name",
            "Company", "PNumber", "FClass");

Map<String,Object> insertParameters = new HashMap<String, Object>();

/* Put Values */
insertParameters.put("Id", 1);
insertParameters.put("Name", "Sam");
insertParameters.put("Company", "123");
insertParameters.put("PNumber", "123");
insertParameters.put("FClass", "N/A");

Number generatedId = insertUser.execute(insertParameters);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM