MSSQL update ResultSet using JDBC - sql-server

MS SQL Server 2019 running on Windows 10, with Java 1.8.0_152 and mssql-jdbc-10.2.1.jre8.jar
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;loginTimeout=30;user=abc;password=def;trustServerCertificate=true");
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql = "use AdventureWorks2019; select * from [HumanResources].[Department]";
ResultSet rs2 = stmt.executeQuery(sql);
rs2.moveToInsertRow();
yields:
com.microsoft.sqlserver.jdbc.SQLServerException: The result set is not updatable.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:237)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.throwNotUpdatable(SQLServerResultSet.java:531)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.verifyResultSetIsUpdatable(SQLServerResultSet.java:537)
at com.microsoft.sql`enter code here`server.jdbc.SQLServerResultSet.moveToInsertRow(SQLServerResultSet.java:5050)
at com.mtas.test.SQL.main(SQL.java:21)
line 21 being the final line shown.
The DDL is:
CREATE TABLE [HumanResources].[Department](
[DepartmentID] [smallint] IDENTITY(1,1) NOT NULL,
[Name] [dbo].[Name] NOT NULL,
[GroupName] [dbo].[Name] NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_Department_DepartmentID] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
This is a copy of a Microsoft example. Can anyone help please?

Related

INSERT in SQL where foreign key is auto-generated in another table [duplicate]

This question already has answers here:
How to insert a row into another table using last inserted ID?
(4 answers)
Closed 4 months ago.
I have a table 1 with an auto-generated primary key in SQL Server. I have a second table 2 where the auto-generated value from table 1 is a foreign key in table 2.
How can I write a query where I can INSERT into table 2, including the auto-generated value from table 1.
Preferably this would also work in a stored procedure.
Generate scripts:
CREATE TABLE [dbo].[POSTADRESSE](
[AdresseID] [int] IDENTITY(1,1) NOT NULL,
[GateNavn] [varchar](50) NULL,
[GateNR] [varchar](10) NULL,
[PostNR] [int] NULL,
[PostSted] [varchar](30) NULL,
CONSTRAINT [XPKPOSTADRESSE] PRIMARY KEY CLUSTERED
(
[AdresseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[KUNDE](
[TelefonNR] [varchar](15) NOT NULL,
[AdresseID] [int] NOT NULL,
[Epost] [varchar](320) NULL,
[Fornavn] [varchar](100) NULL,
[Etternavn] [varchar](100) NULL,
[Passord] [varchar](69) NULL,
CONSTRAINT [XPKKUNDE] PRIMARY KEY CLUSTERED
(
[TelefonNR] ASC,
[AdresseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
This is what I've tried:
INSERT INTO POSTADRESSE(GateNavn, GateNR, PostNR, PostSted)
VALUES ('Storgt', 3, 3901, 'Porsgrunn')
INSERT INTO KUNDE(TelefonNR, AdresseID, Epost, Fornavn, Etternavn, Passord)
VALUES (
47843329,
(SELECT POSTADRESSE.AdresseID FROM POSTADRESSE WHERE POSTADRESSE.GateNavn = 'Storgt'),
'hej#hotmail.se',
'Anton',
'Johanson',
'123abc'
);
Hi #VaBraAnton see this answer will help.
Declare #Identity as int
INSERT INTO POSTADRESSE(GateNavn, GateNR, PostNR, PostSted)
VALUES ('Storgt', 3, 3901, 'Porsgrunn')
Select #Identity=SCOPE_IDENTITY();
INSERT INTO KUNDE(TelefonNR, AdresseID, Epost, Fornavn, Etternavn, Passord)
VALUES (
47843329,
#Identity,
'hej#hotmail.se',
'Anton',
'Johanson',
'123abc'
);
see screen shot

General Trigger that updates a Master/Detail table

I've been tasked with creating a generic Trigger(one that will work on all tabled in my database) that will will fire on Insert, Delete, and Update to capture changes done on a table.
I have 2 new tables a Master Table...
CREATE TABLE [dbo].[DATA_HIL_Master](
[MasterId] [int] IDENTITY(1,1) NOT NULL,
[ReferenceTable] [nvarchar](100) NULL,
[ReferenceId] [int] NULL,
[OperationType] [smallint] NULL,
[Last_UserId_Log] [int] NULL,
[Last_WorkstationId_Log] [int] NULL,
[Last_DateTime_Log] [datetime] NULL, PRIMARY KEY CLUSTERED (
[MasterId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS
= ON) ON [PRIMARY]
) ON [PRIMARY] GO
And then a Detail table...
CREATE TABLE [dbo].[DATA_HIL_Detail](
[DetailId] [int] IDENTITY(1,1) NOT NULL,
[MasterId] [int] NOT NULL,
[ColumnName] [nvarchar](100) NULL,
[OriginalValue] [nvarchar](max) NULL,
[ModifiedValue] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED (
[DetailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
My trigger needs to be able to update these tables with the correct information for that update and than table. For Instance I have another table..
CREATE TABLE [dbo].[CNF_Tax2Package](
[Tax2PackageId] [int] IDENTITY(1,1) NOT NULL,
[TaxPackageId] [int] NOT NULL,
[TaxId] [int] NOT NULL,
[Last_UserId_Log] [int] NULL,
[Last_WorkstationId_Log] [int] NULL,
[Last_DateTime_Log] [datetime] NULL,
PRIMARY KEY CLUSTERED
(
[Tax2PackageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
[Tax2PackageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
EveryTime a record is change in this CNF_Tax2Package table I need to up the History tables with information
I do the following UPdate statement
Update CNF_Tax2Package
set TaxPackageid = 1,
Last_UserID_Log = 1098,
Last_WorkstationID_Log = 77,
Last_DateTime_Log = Getdate()
where Tax2PackageID = 2]
I would insert into the DATA_HIL_Master a row with the following information
[MasterId] = (NEWMasterID) [ReferenceTable] = 'CNF_Tax2Package' [ReferenceId] = 2 ---This is the primary Key of the
---table updated. [OperationType] = 'Update' [Last_UserId_Log] = 1098 [Last_WorkstationId_Log] = 77 [Last_DateTime_Log] getdate()
I would then insert into the DATA_HIL_Detail the following rows.
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'TaxPackageid' [OriginalValue] = '19' [ModifiedValue] = '1'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_UserID_Log' [OriginalValue] = '1954' [ModifiedValue] = '1098'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_WorkstationId_Log' [OriginalValue] = '55' [ModifiedValue] = '77'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_DateTime_Log' [OriginalValue] = '2018-08-18 [ModifiedValue] = getdate()
Understanding that the trigger must be generic enough to handle all tables in my database with different columns, different primary Keys

Update several fields in thousands rows

I have database MS SQL Server 2008 R2 with loading 2000 transactions per second. Tables are:
'lion_Tasks'(uid_obj, order_new, __usn_field_order_new, and more 40 fields)
and
'lion_Tasks_Changes_Parts'(uid_task_cp, uid_user_cp, __usn_entity_cp and more 20 fields )
Web-server get 10.000 objects, in which only one field has changed 'order_new'. Only 3 fields need to be updated in the database. These objects I pass in a table parameter to the stored procedure:
I tried to rewrite this stored procedure several times without any performance changes, it still trips out 10-20 seconds, current version is:
CREATE PROCEDURE dbo.lion_UpdateTasksNewOrder
( #Table TasksNewOrderTableType READONLY)
WITH RECOMPILE AS
BEGIN
DECLARE #ErrorCode int
SET #ErrorCode = -1
UPDATE TasksTable
SET
order_new = t.ORDER_NEW,
__usn_field_order_new = t.USN_ORDER_NEW
FROM dbo.lion_Tasks TasksTable
INNER JOIN #Table t
ON t.UUID_TASK = TasksTable.uid_obj
IF( ##ERROR != 0 )
BEGIN
SET #ErrorCode = -1
GOTO Cleanup
END
UPDATE TasksTableCP
SET
__usn_entity_cp = tcp.USN_ENTITY
FROM dbo.lion_Tasks_Changes_Parts TasksTableCP
INNER JOIN #Table tcp
ON tcp.UUID_TASK = TasksTableCP.uid_task_cp AND tcp.UUID_USER = TasksTableCP.uid_user_cp
IF( ##ERROR != 0 )
BEGIN
SET #ErrorCode = -1
GOTO Cleanup
END
RETURN 0
Cleanup:
RETURN #ErrorCode
END
The temp-database is located on the SSD disk. Maybe someone tell me what to do for acceleration?
The estimated execution plan is:
https://www.brentozar.com/pastetheplan/?id=Byq2JzTwm
Table script:
USE [lion_data]
GO
/****** Object: Table [dbo].[lion_Tasks_Changes_Parts] Script Date: 09/05/2018 11:31:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[lion_Tasks_Changes_Parts](
[uid_obj_cp] [uniqueidentifier] NOT NULL,
[uid_task_cp] [uniqueidentifier] NOT NULL,
[uid_user_cp] [uniqueidentifier] NOT NULL,
[_order_cp] [int] NOT NULL,
[uid_marker_cp] [uniqueidentifier] NOT NULL,
[date_begin_cp] [datetime] NULL,
[date_end_cp] [datetime] NULL,
[readed_cp] [int] NOT NULL,
[collapsed_cp] [int] NOT NULL,
[__usn_entity_cp] [int] NOT NULL,
[__usn_field_order_cp] [int] NOT NULL,
[__usn_field_uid_marker_cp] [int] NOT NULL,
[__usn_field_date_begin_cp] [int] NOT NULL,
[__usn_field_date_end_cp] [int] NOT NULL,
[__usn_field_readed_cp] [int] NOT NULL,
[__usn_field_collapsed_cp] [int] NOT NULL,
[__usn_field_list_tags_cp] [int] NULL,
[Contacts] [nvarchar](max) NULL,
[__usn_field_contacts_cp] [int] NULL,
[uid_user_marker] [uniqueidentifier] NULL,
[__usn_field_uid_user_marker] [int] NULL,
[focus_cp] [int] NULL,
[__usn_field_focus_cp] [int] NULL,
CONSTRAINT [PK_lion_Tasks_Changes_Parts] PRIMARY KEY CLUSTERED
(
[uid_obj_cp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Scripts for indexes:
USE [lion_data]
GO
/****** Object: Index [PK_lion_Tasks] Script Date: 09/05/2018 11:28:44 ******/
ALTER TABLE [dbo].[lion_Tasks] ADD CONSTRAINT [PK_lion_Tasks] PRIMARY KEY CLUSTERED
(
[uid_obj] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [lion_data]
GO
/****** Object: Index [IX_lion_Tasks_CP_Uid_Task] Script Date: 09/05/2018 11:29:17 ******/
CREATE NONCLUSTERED INDEX [IX_lion_Tasks_CP_Uid_Task] ON [dbo].[lion_Tasks_Changes_Parts]
(
[uid_task_cp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
USE [lion_data]
GO
/****** Object: Index [IX_lion_Tasks_CP_Uid_User] Script Date: 09/05/2018 11:29:30 ******/
CREATE NONCLUSTERED INDEX [IX_lion_Tasks_CP_Uid_User] ON [dbo].[lion_Tasks_Changes_Parts]
(
[uid_user_cp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Create a stored procedure to populate a table from other (multiple) table columns

I need to create a stored procedure transaction that will pull data from two tables and create a random integer to populate a third table (dbo.patient_address).
I want the following, but I am having a hard time understanding how to script this as a stored procedure.
dbo.address AddressID = dbo.patient_address AddressID,
dbo.patient PatientID = dbo.patient_address PatientID,
RAND is an integer between 1-3 (see dbo.addresstype) = dbo.patient_address AddressTypeID
Below are create statements of all of these tables.
ADDRESS TABLE - 30000 rows in place (complete data set)
CREATE TABLE [dbo].[ADDRESS](
[AddressID] [int] NOT NULL,
[StreetAddress] [varchar](50) NULL,
[City] [varchar](50) NULL,
[State] [varchar](50) NULL,
[PostalCode] [varchar](50) NULL,
CONSTRAINT [ADDRESS_PK] PRIMARY KEY CLUSTERED
(
[AddressID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
PATIENT TABLE - 30000 rows in place (complete data set)
CREATE TABLE [dbo].[PATIENT](
[PatientID] [int] NOT NULL,
[PatientFName] [varchar](50) NOT NULL,
[PatientLName] [varchar](50) NOT NULL,
[GenderID] [int] NOT NULL,
[DateOfBirth] [date] NOT NULL,
CONSTRAINT [PATIENT_PK] PRIMARY KEY CLUSTERED
(
[PatientID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ADDRESS TYPE - 3 choices (home, billing, work) – integer between 1 - 3
CREATE TABLE [dbo].[ADDRESS_TYPE](
[AddressTypeID] [int] NOT NULL,
[AddressTypeName] [varchar](10) NOT NULL,
[AddressTypeDescr] [varchar](10) NULL,
CONSTRAINT [ADDRESS_TYPE_PK] PRIMARY KEY CLUSTERED
(
[AddressTypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[ADDRESS_TYPE]
([AddressTypeID],[AddressTypeName],[AddressTypeDescr])
Values ('1','Home','Home'), ('2','Bill','Billing'), ('3','Work','Work')
This is the final table that I want to populate from all of the above tables using a stored procedure transaction.
CREATE TABLE [dbo].[PATIENT_ADDRESS](
[PatientID] [int] NOT NULL,
[AddressID] [int] NOT NULL,
[AddressTypeID] [int] NULL,
CONSTRAINT [PATIENT_ADDRESS_PK] PRIMARY KEY CLUSTERED
(
[PatientID] ASC,
[AddressID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Try this:
INSERT INTO PATIENT_ADDRESS
SELECT PatientID, AddressID,
CONVERT(INT,(ABS(CHECKSUM(NEWID())/2148000000.))*3)+1 AS AddressTypeID
FROM (
SELECT PatientID, ROW_NUMBER() OVER (ORDER BY PatientID) AS RowNum
FROM dbo.PATIENT
) x
INNER JOIN (
SELECT AddressID, ROW_NUMBER() OVER (ORDER BY AddressID) AS RowNum
FROM dbo.ADDRESS
) y ON x.RowNum = y.RowNum

SQL Server 2008: Collation ignored in unique index?

I've created a compound unique index on my table:
CREATE TABLE [dbo].[SearchIndexWord](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CatalogID] [int] NOT NULL,
[Word] [nvarchar](100) NOT NULL,
CONSTRAINT [PK_SearchIndexWord] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
CREATE UNIQUE NONCLUSTERED INDEX [IX_SearchIndexWord] ON [dbo].[SearchIndexWord]
(
[Word] ASC,
[CatalogID] ASC
)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
The collation for the entire database is set to SQL_Latin1_General_CP1_CI_AS. When I run the following T-SQL, it prints 'Does not equal':
IF 'm3/h' = 'm³/h'
PRINT 'Equals'
ELSE
PRINT 'Does not equal'
Then, if I try the following insert statement:
INSERT INTO [SearchIndexWord] (Word, CatalogID) VALUES ('m3/h', 1), ('m³/h', 1)
I get the following error message:
Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.SearchIndexWord' with unique index 'IX_SearchIndexWord'.
Why is this? I couldn't find it in the docs, but I assume the condition of two keys being duplicate is examined using the configured collation.
I've checked the table, column and index collation by the way, and they're all equal to the database collation.
Try this:
IF CAST('m3/h' AS NVARCHAR(100)) = CAST('m³/h' AS NVARCHAR(100))
PRINT 'Equals'
ELSE
PRINT 'Does not equal'
For me, this returns 'Equals' which explains why you're getting the duplicate key row error.
I suspect the values in the code IF 'm3/h' = 'm³/h' are created as VARCHAR.

Resources