0

the FROM line in the stored procedure is taken from multiple guides (some on stackoverflow), but it can't seem to work (no matter what i pass to the SP from java).

server is on my machine. the java file is picked on the same path as the same file in the SP comment under the FROM.

bulk insert works (tested) with commented path when executed as a normal query in sql server.

using jdbc4, sql server 2008r2.


stored procedure:

CREATE PROCEDURE importUsers
@CSVPath NVARCHAR(200) /*the path parameter im using.*/
AS
BEGIN
SET NOCOUNT ON
SET XACT_ABORT ON

CREATE TABLE #Inserts(
rowNo int IDENTITY(1,1),
UserNo int,
email varchar(255),
nickName varchar(20),
registrationDate Date
);

BEGIN TRAN fetchFromFile

BULK INSERT #Inserts
FROM ''' + @CSVPath + '''
/*FROM 'e:\csv\test.csv'    THIS PATH WORKS*/
    WITH
    (
        FIELDTERMINATOR = '|',
        ROWTERMINATOR = '\n'
    )

    IF @@ERROR <> 0
    BEGIN
        ROLLBACK TRAN fetchFromFile
        GOTO ON_ERROR
    END

    IF @@ROWCOUNT > 0
    BEGIN

/*copy duplicates with higher rowNumber in file, 
        -- or ones that already exist in tblUser to updates table.*/
        SELECT *
        INTO #Updates
        FROM #Inserts O
        WHERE userNo IN (SELECT UserNo
                         FROM tblUser) OR
              EXISTS (SELECT *
                      FROM #Inserts I
                      WHERE O.UserNo = I.UserNo AND I.rowNo < O.rowNo)

        IF @@ERROR <> 0
        BEGIN
            ROLLBACK TRAN fetchFromFile
            GOTO ON_ERROR
        END

        /*keep only inserts in the inserts table.*/
        DELETE FROM #Inserts 
        WHERE rowNo IN (SELECT rowNo 
                        FROM #Updates)

        /*keep only the latest updates of a certain user.*/
        DELETE FROM #Updates
        WHERE EXISTS (SELECT * 
                          FROM #Updates I 
                          WHERE I.UserNo = #Updates.UserNo AND I.rowNo > #Updates.rowNo)

        IF @@ERROR <> 0
        BEGIN
            ROLLBACK TRAN fetchFromFile
            GOTO ON_ERROR
        END

        /*try inserting the inserts.*/
        INSERT INTO tblUser(UserNo, email, nickName, registrationDate)
        SELECT I.UserNo, I.email, I.nickName, I.registrationDate
        FROM #Inserts I

        IF @@ERROR <> 0
        BEGIN
            ROLLBACK TRAN fetchFromFile
            GOTO ON_ERROR
        END

        /*try updating the updates.*/
        UPDATE tblUser
        SET email = S.email, nickName = S.nickName, registrationDate = S.registrationDate
        FROM #Updates S
        WHERE S.UserNo = tblUser.UserNo

    END

COMMIT TRAN fetchFromFile

ON_ERROR:
PRINT 'rollback occured!';  

END

java snippets:

{ ....   // environment where the file/path is picked...
         FileChooser fileChooser = new FileChooser();
     fileChooser.setTitle("open csv file");
     fileChooser.getExtensionFilters().add(new ExtensionFilter("CSV files", "*.csv", "*.txt"));
     File potentialFile = fileChooser.showOpenDialog(ViewLogic.getPrimaryStage());
     if (potentialFile != null){
         selectedFile = potentialFile;
         filePathField.setText(selectedFile.getAbsolutePath());
         btnImport.setDisable(false);
     }

ViewLogic.importData(selectedFile.getCanonicalPath(), E_ImportType.USER);
}


// environment that executes the SP.
public boolean importData(String path ....
......
cstmt = database.getConnection().prepareCall("{call dbo.importUsers(?)}";
cstmt.setNString("CSVPath", path);
cstmt.executeUpdate();
Igal Klebanov
  • 348
  • 2
  • 15
  • Can you change your SP to `FROM @CSVPath ` – JavaGhost Oct 06 '15 at 18:45
  • first thing i've tried.. gives an Incorrect Syntax error near @CSVPath Expecting ID, INTEGER, QUOTED_ID, STRING, or TEXT_LEX.. – Igal Klebanov Oct 06 '15 at 19:14
  • 1
    Perhaps you can build your BULK INSERT statement as a string and then use `EXECUTE` or `sp_executesql` to run it? – Gord Thompson Oct 06 '15 at 19:47
  • I found a useful example [here](http://www.databasejournal.com/features/mssql/article.php/3325701/Import-multiple-Files-to-SQL-Server-using-T-SQL.htm) Basically, SQL expects it to a fixed string and not a string identifier. – JavaGhost Oct 06 '15 at 19:54
  • http://stackoverflow.com/a/4051325/1060984 just tried this answer's sp_executesql part.. it doesn't throw an exception... but at the same time.... it doesn't update the table (i've made changes to the csv file to test) @GordThompson – Igal Klebanov Oct 06 '15 at 20:31
  • http://paste.ofcode.org/ynppCz4t6f54EC52ArUyRN here's my SP after trying to save the bulk query as a string and than sp_executesql it.. no matter how the CSV file looks (i tried 1 liner with a user that doesn't exist), it just doesn't do anything. no exceptions.. no changes to the table. – Igal Klebanov Oct 06 '15 at 20:46
  • You don't happen to be passing the path with forward-slash separators ("e:/csv/test.csv") instead of backslash separators ("e:\csv\test.csv") ...? Java might treat them interchangably under Windows, but T-SQL may not. – Gord Thompson Oct 06 '15 at 20:55
  • printed it in java before posting on stackO. all File's getPath() methods are with \'s for me. – Igal Klebanov Oct 06 '15 at 21:28
  • i think i solved this issue, it was the @@ROWCOUNT check.. it's not affected by the EXEC.. so it couldn't be >0 for the transaction to continue beyond @bulk... – Igal Klebanov Oct 06 '15 at 21:33

0 Answers0