首页 文章

使用JAVA将Arraylst <Arraylist <String >>传递给MSSQL存储过程?

提问于
浏览
1

在这里,我试图将List传递给存储过程,但收到以下错误:

操作数类型冲突:nvarchar与UserType不兼容

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

UserDefined数据类型

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类

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();
                                }

                }

}

堆栈跟踪:

com.microsoft.sqlserver.jdbc.SQLServerException:操作数类型冲突:nvarchar与com.microsoft.sqlserver.jdbc.SQLServerStatement中的com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)中的UserType不兼容 . getNextResult(SQLServerStatement.java:1454)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)位于com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416)的com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement) .java:185)com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:160)at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedSta) tement.java:320)at carma.TestInsurence.main(TestPreload.java:71)

1 回答

  • 0

    你正在做 {call UserDetails(?,?,?)} ,但你的存储过程不带任何参数 . 您需要更改存储过程,如下所示:

    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
    

    更改您的代码如下:

    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();
    

    此外,我不明白为什么要通过调用存储过程在表中插入数据 . 您可以简单地使用 PreparedStatement 来执行此操作 . 这是一个例子:

    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();
          }
       }
    }
    

    如果您使用的是Spring Framework,则可以使用JdbcTemplate轻松完成 . 这是一个例子:

    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);
    

相关问题