Loss of accents when inserting some UTF8 data into nvarchar - sql-server

Create table:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[StringsTest](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](max) NOT NULL,
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] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
Insert data (Latvian):
INSERT INTO [dbo].[StringsTest]
([Value])
VALUES
('TĀDS KĀDU JŪS')
GO
Select:
SELECT * FROM [dbo].[StringsTest]
Results have lost accents:
Id Value
1 TADS KADU JUS

Use an N before your Unicode string to mark it as such.
INSERT [dbo].[StringsTest]
([Value])
VALUES
(N'TĀDS KĀDU JŪS')

Related

Auditing SQL Server - who is changing what and when? SOX complaince

In my organization, we are doing very limited logging or any sort to capture who is changing what and when.
I am seeking help here to understand what should be the best practices to capture any logging whatsoever happening in our SQL Server database.
I am thinking of going over the tables based on the important business uses cases that a user can perform with the application and then making an xl file with the following fields so that I keep this file as a reference for myself.
My question: is there any other better way to capture the current change in the database, and is there a way in SQL Server that I use to find out if we are capturing any logging in the database?
We don't have any CDC implementation or C2 audit tracing enables or change tacking enabled.
Management want's to leverage the data captured in the database tables.
I am working on a similar project, you can use below design, i am explaining with student subject example
CREATE TABLE [dbo].[AudRel](
[AudId] [int] IDENTITY(1,1) NOT NULL,
[AudTableName] [varchar](100) NULL,
[AudFieldName] [varchar](100) NULL,
[AudFieldID] [varchar](30) NULL,
CONSTRAINT [PK_AuditRel] PRIMARY KEY CLUSTERED
(
[AudId] 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 TABLE [dbo].[Student](
[StudentID] [int] IDENTITY(1,1) NOT NULL,
[StudentName] [varchar](100) NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[StudentID] 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 TABLE [dbo].[Student_Audit](
[ID] [int] IDENTITY(1,1) NOT NULL,
[StudentID] [int] NOT NULL,
[StudentName] [varchar](100) NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[StudentSubject](
[SSID] [int] IDENTITY(1,1) NOT NULL,
[StudentID] [int] NULL,
[SubjectID] [int] NULL,
CONSTRAINT [PK_StudentSubject] PRIMARY KEY CLUSTERED
(
[SSID] 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 TABLE [dbo].[StudentSubject_Audit](
[ID] [int] IDENTITY(1,1) NOT NULL,
[SSID] [int] NOT NULL,
[StudentID] [int] NULL,
[SubjectID] [int] NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Subject](
[SubjectID] [int] IDENTITY(1,1) NOT NULL,
[SubjectName] [varchar](50) NULL,
CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED
(
[SubjectID] 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 TABLE [dbo].[Subject_Audit](
[ID] [int] IDENTITY(1,1) NOT NULL,
[SubjectID] [int] NOT NULL,
[SubjectName] [varchar](50) NULL
) ON [PRIMARY]
SET IDENTITY_INSERT [dbo].[AudRel] ON
INSERT [dbo].[AudRel] ([AudId], [AudTableName], [AudFieldName], [AudFieldID]) VALUES (1, N'Student', N'StudentName', N'StudentID')
INSERT [dbo].[AudRel] ([AudId], [AudTableName], [AudFieldName], [AudFieldID]) VALUES (2, N'Subject', N'SubjectName', N'SubjectID')
SET IDENTITY_INSERT [dbo].[AudRel] OFF
SET IDENTITY_INSERT [dbo].[Student] ON
INSERT [dbo].[Student] ([StudentID], [StudentName]) VALUES (1, N'Alex')
INSERT [dbo].[Student] ([StudentID], [StudentName]) VALUES (2, N'DSouza')
SET IDENTITY_INSERT [dbo].[Student] OFF
SET IDENTITY_INSERT [dbo].[StudentSubject] ON
INSERT [dbo].[StudentSubject] ([SSID], [StudentID], [SubjectID]) VALUES (1, 1, 1)
INSERT [dbo].[StudentSubject] ([SSID], [StudentID], [SubjectID]) VALUES (2, 2, 1)
INSERT [dbo].[StudentSubject] ([SSID], [StudentID], [SubjectID]) VALUES (3, 2, 2)
SET IDENTITY_INSERT [dbo].[StudentSubject] OFF
SET IDENTITY_INSERT [dbo].[Subject] ON
INSERT [dbo].[Subject] ([SubjectID], [SubjectName]) VALUES (1, N'English')
INSERT [dbo].[Subject] ([SubjectID], [SubjectName]) VALUES (2, N'Mathematics')
SET IDENTITY_INSERT [dbo].[Subject] OFF
and then use below query to dynamically fetch fields have been changed. From the UI you need to pass the AudRelID
DECLARE #TableName VARCHAR(100),#FieldName VARCHAR(100),#FieldID VARCHAR(100)
SELECT #TableName = [AudTableName]
, #FieldName=[AudFieldName]
, #FieldID=[AudFieldID]
FROM [dbo].[AudRel] WHERE [AudId] = 1 -- (Ex : StudentHistory)
DECLARE #SQL NVARCHAR(MAX) = N'
SELECT ID,' + #FieldID +
',' + #FieldName + ' FROM ' + #TableName + '_Audit ' + ' WHERE ' + #FieldID + ' = '
+ Convert(varchar(20),#FieldID)
print #SQL
EXECUTE sp_executesql #SQL

Computed column on table is giving error when triggers are used on table

I am getting below error and if I don't use computed column then it works fine .
Msg 213, Level 16, State 1, Procedure test1tri, Line 3 [Batch Start Line 24]
Column name or number of supplied values does not match table definition.
this is sample I am using:
drop table test2
CREATE TABLE test2 ([ID] [INT], [NAME] [VARCHAR](100), [ADDRESS] [VARCHAR](100)
CONSTRAINT [PK_test2] 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]
ALTER TABLE test2
ADD full_name AS (name + ' ' + address) persisted;
drop table test3
CREATE TABLE test3 ([$delete] [bit] NULL,[ID] [INT], [NAME] [VARCHAR](100), [ADDRESS] [VARCHAR](100)
CONSTRAINT [PK_test3] UNIQUE 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]
GO
ALTER TABLE test3
ADD full_name AS (name + ' ' + address) persisted;
CREATE TRIGGER [test1tri] ON [test2]
INSTEAD OF INSERT AS
INSERT INTO [test3] SELECT 0,* FROM inserted
GO
While you want to insert new record to table you should not provide value for the computed column. So you can rewrite your trigger as below:
CREATE TRIGGER [test1tri] ON [test2]
INSTEAD OF INSERT AS
INSERT INTO [test3] SELECT 0,
Inserted.ID,
Inserted.NAME,
Inserted.ADDRESS FROM inserted
GO

How to limit the value range that can be placed in a column?

I am a beginner in SQL,
I have a table with GroupRole column and Age column.
CREATE TABLE [Persons](
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[FullName] [varchar](70) NULL,
[Age] [int] NULL,
[GroupRole ] [varchar](30) NULL
CONSTRAINT [PK_Persons] PRIMARY KEY CLUSTERED
(
[PersonID] 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
I want to limit the value range that can be placed in an age column lower 30
and GroupRole column equal 'Admin'.
I do not want to do this in the c# code.
How can I do it?
this have easy way:
ALTER TABLE Persons
ADD CONSTRAINT CHK_PersonAge CHECK (Age>=30 AND GroupRole ='Admin');
You need to use Check Constraints. They are part of your table's metadata and define conditions to be checked every time, when the data is modified or inserted in the table. If these conditions are not met, the DML operation will fail with an error.
You need to modify your CREATE TABLE statement as follows:
CREATE TABLE [Persons](
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[FullName] [varchar](70) NULL,
[Age] [int] NULL CONSTRAINT CHK_Age CHECK ([Age] < 30),
[GroupRole] [varchar](30) NULL CONSTRAINT CHK_GroupRole CHECK ([GroupRole] in ('Admin'))
CONSTRAINT [PK_Persons] PRIMARY KEY CLUSTERED
(
[PersonID] 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

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

Scalar_Variable Function with Multiple AND statements returning "NULL"

Im writing Scalar-Variable function in sql to return a strName mapped by an integer. The following is my script:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Lookup_BSource_Value]
(
-- Add the parameters for the function here
#AVal nvarchar(100)
)
RETURNS nvarchar(100)
AS
BEGIN
-- Declare the return variable here
DECLARE #Val nvarchar(100)
SELECT #Val = Val
FROM SMBase
WHERE AName = 'a_source'
AND (OTypeCode = 1084)
AND (AVal = (#AVal))
RETURN #Val
END
I should be getting the result of "BA" but am receiving a "NULL". Is my syntax correct for the multiple AND statements?
EDIT*
Before use the function in my SSIS package I am just doing a simple
SELECT dbo.Lookup_BSource_Value(XXXXXXXXX)
This gives me the null.
The following is the logical schema of the table I am querying:
USE [MSCRM_M_RC]
GO
/****** Object: Table [dbo].[SMBase] Script Date: 1/21/2014 6:29:48 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SMBase](
[OTypeCode] [int] NOT NULL,
[AName] [nvarchar](100) NOT NULL,
[AVal] [int] NOT NULL,
[LaId] [int] NOT NULL,
[OrgId] [uniqueidentifier] NOT NULL,
[Val] [nvarchar](4000) NULL,
[DOrder] [int] NULL,
[VNumber] [timestamp] NULL,
[SMId] [uniqueidentifier] NOT NULL,
CONSTRAINT [cndx_PrimaryKey_SMap] PRIMARY KEY CLUSTERED
(
[SMId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY],
CONSTRAINT [UQ_SMap] UNIQUE NONCLUSTERED
(
[OTCode] ASC,
[AName] ASC,
[AValue] ASC,
[LaId] ASC,
[OrgId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[SMBase] ADD CONSTRAINT [DF_SMa_SMId] DEFAULT (newid()) FOR [SMId]
GO
*EDIT**
The following is my logical schema of my StringMapTable:
StringMap(SMID pk, OTypeCode,AName, AVal, LaID, OrgID fk, Val, DOrder, VNumber)
The following is my logical schema of my TPTRepair Table:
TPTRepair(TPTRepairID pk, Name, Source, TT, LTHrs, CustID fk, PID fk)
The problem is the following:
The "Source" field is an integer in TPTRepair. I'm writing the following scalar-function to reference StringMap to return the string value from Value column in StringMap. I have to have a couple ands because AName hase to = 'a_source' and OTypeCode has to = 1084.
My scalar-function results in a NULL and shouldn't be. Is my syntax correct from the multiple AND statement in my scalar-function above?
So Im apparently an idiot. It was the most simplest thing. OTypeCode was to = '10084' rather than '1084'. Im an intern. Please forgive me ;) This was the answer.

Resources