Why TEXTIMAGE_ON and make table as FileStream - sql-server

I have a table on an existing SQL Server 2014 database as follows:
CREATE TABLE [dbo].[Files](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Content] [varbinary](max) NULL,
[Created] [datetime2](7) NOT NULL,
[Flag] [nvarchar](100) NULL,
[Key] [uniqueidentifier] NOT NULL,
[MimeType] [nvarchar](400) NOT NULL,
[Name] [nvarchar](400) NULL,
[Pack] [uniqueidentifier] NOT NULL,
[Slug] [nvarchar](400) NULL,
[Updated] [datetime2](7) NOT NULL,
CONSTRAINT [PK_File] 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]
What is TEXTIMAGE_ON and why not just [PRIMARY]?
How can I change this table to use FileStream? So it would have:
[Key] uniqueidentifier rowguidcol not null
constraint DF_File_Key default newid()
constraint UQ_File_Key unique ([Key]),
And
) filestream_on ???
UPDATE
I have the following TSQL:
exec sp_configure filestream_access_level, 2
reconfigure
alter table dbo.Files
set (filestream_on = 'default')
alter table dbo.Files
alter column [Key] add rowguidcol;
alter table dbo.Files
alter column Content filestream;
alter table dbo.Files
add constraint DF__File__Content default (0x),
constraint DF__File__Key default newid(),
constraint UQ__File__Key unique ([Key]);
go
But when I run it I get the error:
Incorrect syntax for definition of the 'TABLE' constraint.
I am using "default" because I want to use the default filegroup.
What am I missing?

From msdn:
SET ( FILESTREAM_ON = { partition_scheme_name | filestream_filegroup_name | "default" | "NULL" } )
Applies to: SQL Server 2008 through SQL Server 2016.
Specifies where FILESTREAM data is stored.
ALTER TABLE with the SET FILESTREAM_ON clause will succeed only if the table has no FILESTREAM columns. The FILESTREAM columns can be added by using a second ALTER TABLE statement.
The TEXTIMAGE_ON is used by default on tables with big columns (nvarchar(max), varbinary(max) etc as mentioned here:
TEXTIMAGE_ON is not allowed if there are no large value columns in the table. TEXTIMAGE_ON cannot be specified if <partition_scheme> is specified. If "default" is specified, or if TEXTIMAGE_ON is not specified at all, the large value columns are stored in the default filegroup. The storage of any large value column data specified in CREATE TABLE cannot be subsequently altered.)

Related

How can I set the date of every row in a table to the current date?

I have this SQL Server table:
CREATE TABLE [dbo].[Synonym]
(
[SynonymId] [int] NOT NULL,
[WordFormId] [int] NOT NULL,
[Ascii] AS (ascii([Text])) PERSISTED,
[Text] [varchar](max) NOT NULL,
[Version] [timestamp] NULL,
[CreatedBy] [int] NULL,
[CreatedDate] [datetime] NULL,
[ModifiedBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
PRIMARY KEY CLUSTERED ([SynonymId] 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]
How can I set the CreatedDate to the current date for all of the rows?
If want to save the date when the record was created, add a default constraint to the table:
ALTER TABLE [Synonym] ADD CONSTRAINT createdDate DEFAULT GETDATE() FOR [CreatedDate]
Then if you insert a record you don't need to specify the createdDate and get the current date value.
If you want to set the date for all existing records simply run an update
UPDATE [Synonym] SET [CreatedDate] = GETDATE()
or for all records whose CreatedDate is null:
UPDATE [Synonym] SET [CreatedDate] = GETDATE() WHERE [CreatedDate] IS NULL
Select Table Column Name where you want to get default value of current date:
ALTER TABLE [dbo].[Table_Name]
ADD CONSTRAINT [Constraint_Name]
DEFAULT (getdate()) FOR [Column_Name]
Alter table query:
Alter TABLE [dbo].[Table_Name]
(
[PDate] [datetime] Default GetDate()
)
you can also do this from SSMS GUI.
Put your table in design view (Right click on table in object
explorer->Design)
Add a column to the table (Click on the column you
want to update if it already exists)
In Column Properties, enter
(getdate()) in Default Value or Binding field as pictured below

How do you deal with foreign keys, unique indexes and default constraints when using a shadow table copy and rename?

I have a large table in a MSSQL 2008 database, to which I need to add a new column, set a value on that new column and then make it not null.
Because the table is large, it keeps timing out on our deployment process. I read that I can use a shadow table and SELECT INTO.., then use sp_rename to replace the original table. As per this answer: https://stackoverflow.com/a/19141346/119624
The table has lots of foreign keys, indexes and constraints. I'm slightly confused as to how I should deal with those.
I assume that the process is as below. But I would appreciate it if someone could confirm whether I'm doing this in the optimum way.
Imagine this is my current table:
CREATE TABLE [dbo].[MyTable](
[MyTableId] [int] IDENTITY(1,1) NOT NULL,
[SomeFkId] [int] NOT NULL,
[IsLocked] [bit] NOT NULL CONSTRAINT [DF_MyTable_IsLocked] DEFAULT ((0)),
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[MyTableId] 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
ALTER TABLE [dbo].[MyTable] WITH CHECK
ADD CONSTRAINT [FK_MyTable_SomeFk] FOREIGN KEY([SomeFkId])
REFERENCES [dbo].[SomeFk] ([SomeFkId])
GO
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_SomeFk]
GO
I now want to add a new shadow table. Do I need to create the table with the defaults and constraints like so?
CREATE TABLE [dbo].[MyTableShadow](
[MyTableId] [int] IDENTITY(1,1) NOT NULL,
[SomeFkId] [int] NOT NULL,
[SomeColumn] [int] NOT NULL,
[IsLocked] [bit] NOT NULL CONSTRAINT [DF_MyTableShadow_IsLocked] DEFAULT ((0)),
[NewColumn] [int] NOT NULL,
CONSTRAINT [PK_MyTableShadow] PRIMARY KEY CLUSTERED
(
[MyTableId] 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
ALTER TABLE [dbo].[MyTableShadow] WITH CHECK
ADD CONSTRAINT [FK_MyTableShadow_SomeFk] FOREIGN KEY([SomeFkId])
REFERENCES [dbo].[SomeFk] ([SomeFkId])
GO
ALTER TABLE [dbo].[MyTableShadow] CHECK CONSTRAINT [FK_MyTableShadow_SomeFk]
GO
Then do the SELECT INTO...
SELECT MyTable.*, MyTable.SomeColumn -- copying value
INTO MyTableShandow
FROM MyTable
Then do the rename:
EXEC sp_rename 'MyTable', 'MyTableOld'
EXEC sp_rename 'MyTableShadow', 'MyTable'
Then do the drop:
DROP TABLE MyTableOld
Then rename the constraints and foreign keys:
EXEC sp_rename 'PK_MyTableShadow', 'PK_MyTable', 'object' -- PK
EXEC sp_rename 'FK_MyTableShadow_SomeFk', 'FK_MyTable_SomeFk', 'object' -- FK
EXEC sp_rename 'DF_MyTableShadow_IsLocked', 'DF_MyTable_IsLocked', 'object' -- DF
Is that the correct process, or is there another easier way? (I have a table that has a lot of FKs and constraints, so I'm trying to reduce the pain!

Add a IDENTITY to a column in SQL SERVER 2008

create table stud(
Student_Id int primary key,
Student_Name varchar(30),
Student_surname varchar(12),
Student_Initial varchar(10))
I had created a table stud. Now i want to add Identity to Student_Id column using alter query
alter table stud alter column student_Id int identity
I get error as
Incorrect syntax near the keyword 'identity'.
ALTER TABLE MyTable
ADD ID INT IDENTITY(1,1) NOT NULL
You cannot make an already existing column as an IDENTITY column. Either you drop and recreate the table with the column marked as IDENTITY', or drop the column and add a newIDENTITY` column.
If Stud contains data, you could always make a shadow table, e.g. Stud2, which contains the Identity column, then run
ALTER TABLE dbo.stud SWITCH TO dbo.stud2
Then you can reseed Stud2, drop Stud, and rename Stud2 to Stud.
That way you can keep the data while dropping/recreating the table with Identity.
Syntax:
IDENTITY [ (seed , increment) ]
alter your table like as this:
create table stud(
Student_Id int IDENTITY(1,1) primary key,
Student_Name varchar(30),
Student_surname varchar(12),
Student_Initial varchar(10));
you can use below query to set identity
CREATE TABLE [dbo].[stud](
[Student_Id] [int] IDENTITY(1,1) NOT NULL,
[Student_Name] [varchar](30) NULL,
[Student_surname] [varchar](12) NULL,
[Student_Initial] [varchar](10) NULL,
PRIMARY KEY CLUSTERED
(
[Student_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
SET ANSI_PADDING OFF
GO

altering DEFAULT constraint on column SQL Server

I have an SQL script for creating a table, i would like the default of all but a few columns to be "" the others require a integer default of 0
The following creates the table. Some columns are removed because there are lots
CREATE TABLE [dbo].[PMIPatients]
(
[PID] [varchar](30) NOT NULL,
[PatientFirstName] [varchar](30) NULL,
[PatientLastName] [varchar](30) NULL,
[PatientDOB] [varchar](30) NULL,
[PatientDoctor] [varchar](30) NULL,
[PatientDiet] [varchar](50) NULL,
[PatientFallRiskLevel] [int] NULL,
[BedId] [int] NULL,
[BedDisplayInfo] TEXT NOT NULL DEFAULT ''
CONSTRAINT [PK_HL7Patient] PRIMARY KEY CLUSTERED
([PID] 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]
I wish to set a different default on selected columns, the following code does not work as it says that there is already a default constraint set. So i assumne i have to drop the constraint first.
ALTER TABLE [dbo].[PMIPatients] ADD
DEFAULT ((0))
FOR [PatientFallRiskLevel]
http://www.w3schools.com/sql/sql_default.asp says the follow code should be able to drop the DEFAULT like this
ALTER TABLE Persons
ALTER COLUMN City DROP DEFAULT
but i get a syntax error on DEFAULT
How do i alter/drop the DEFAULT constraint of specific columns
When you add a default, you should use names for your constraints. This way you can later refer to those constraints by name.
ALTER TABLE [dbo].[PMIPatients] ADD CONSTRAINT [PatientFallRiskLevel_Default] DEFAULT ((0)) FOR PatientFallRiskLevel
Then you can drop it using:
ALTER TABLE [dbo].[PMIPatients] DROP CONSTRAINT [PatientFallRiskLevel_Default]
The syntax is:
ALTER TABLE [dbo].[PMIPatients] ADD CONSTRAINT NameYourConstraint DEFAULT ((0)) FOR [PatientFallRiskLevel]
ALTER TABLE [dbo].[PMIPatients] DROP CONSTRAINT NameYourConstraint
When you create a constraint without a name, the SQL Server automatically create internal name. It can be see in the [sys].[default_constraints].
For example:
DROP TABLE IF EXISTS [dbo].[StackOverflow];
CREATE TABLE [dbo].[StackOverflow]
(
[colA] INT
,[colB] INT DEFAULT(0)
,[colC] CHAR(1) DEFAULT('x')
);
GO
SELECT *
FROM [sys].[default_constraints]
WHERE [parent_object_id] = OBJECT_ID('[dbo].[StackOverflow]');
GO
You can use the name to drop the constraint.
If you have more of them, you can use one of the scripts below:
-- all suported editions
DECLARE #DynamicTSQLStataement NVARCHAR(MAX)
,#TableNameWithSchema SYSNAME;
SET #TableNameWithSchema = '[dbo].[StackOverflow]';
SELECT #DynamicTSQLStataement = STUFF
(
(
SELECT ';ALTER TABLE ' + #TableNameWithSchema + ' DROP CONSTRAINT ' + QUOTENAME([name])
FROM [sys].[default_constraints]
WHERE [parent_object_id] = OBJECT_ID('[dbo].[StackOverflow]')
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
);
EXEC sp_executesql #DynamicTSQLStataement;
GO
or
-- SQL Server 2016 or later
DECLARE #DynamicTSQLStataement NVARCHAR(MAX)
,#TableNameWithSchema SYSNAME;
SET #TableNameWithSchema = '[dbo].[StackOverflow]';
SELECT #DynamicTSQLStataement = STRING_AGG('ALTER TABLE ' + #TableNameWithSchema + ' DROP CONSTRAINT ' + QUOTENAME([name]), ';')
FROM [sys].[default_constraints]
WHERE [parent_object_id] = OBJECT_ID('[dbo].[StackOverflow]');
EXEC sp_executesql #DynamicTSQLStataement;
GO

Sql Server: Compare varchar type value in where clause doesn't return results

I have a SQL Server 2012 Web Edition within the AWS RDS database service. The collation is the default one: SQL_Latin1_General_CP1_CI_AS.
In one of the tables I have a column MODIFIED_BY of type varchar(128) - the column collation is default.
The usual values stored into this column are GUIDS with the exception of a few which are hard coded to System. As you can tell it's a table for storing the audit trail transactions where we store the id or System if modification was done as part of the migration.
Anyways - everything above was just the context. Now the weird problem:
I get no records if I run the following, although I should have:
select *
from AUDIT_LOG_TRANSACTIONS alt
where lower(ltrim(rtrim(alt.MODIFIED_BY)))='system'
or
select *
from AUDIT_LOG_TRANSACTIONS alt
where lower(ltrim(rtrim(alt.MODIFIED_BY)))=convert(varchar,'system')
or
select *
from AUDIT_LOG_TRANSACTIONS alt
where lower(ltrim(rtrim(alt.MODIFIED_BY)))=convert(varchar(128),'system')
I get records if I run the following:
select *
from AUDIT_LOG_TRANSACTIONS alt
where alt.MODIFIED_BY like '%System%'
or
select *
from AUDIT_LOG_TRANSACTIONS alt
where lower(ltrim(rtrim(CAST(alt.MODIFIED_BY AS nvarchar(max)))))='system'
UPDATE
Here's the table create script:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[AUDIT_LOG_TRANSACTIONS](
[AUDIT_LOG_TRANSACTION_ID] [int] IDENTITY(1,1) NOT NULL,
[DATABASE] [nvarchar](128) NOT NULL,
[TABLE_NAME] [nvarchar](261) NOT NULL,
[TABLE_SCHEMA] [nvarchar](261) NOT NULL,
[AUDIT_ACTION_ID] [tinyint] NOT NULL,
[HOST_NAME] [varchar](128) NOT NULL,
[APP_NAME] [varchar](128) NOT NULL,
[MODIFIED_BY] [varchar](128) NOT NULL,
[MODIFIED_DATE] [datetime] NOT NULL,
[AFFECTED_ROWS] [int] NOT NULL,
[SYSOBJ_ID] AS (object_id([TABLE_NAME])),
PRIMARY KEY CLUSTERED
(
[AUDIT_LOG_TRANSACTION_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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[AUDIT_LOG_TRANSACTIONS] ADD DEFAULT (db_name()) FOR [DATABASE]
GO
ALTER TABLE [dbo].[AUDIT_LOG_TRANSACTIONS] ADD CONSTRAINT [DF_AUDIT_LOG_TRANSACTIONS_MODIFIED_BY] DEFAULT ('System') FOR [MODIFIED_BY]
GO
Could it be there are some "hard to see" characters in your string ?
To eliminate this possibility, I would run a query like this:
select alt.*, LEN(alt.MODIFIED_BY) as 'Length', cast(alt.MODIFIED_BY as varbinary(max)) as 'Bytes' from AUDIT_LOG_TRANSACTIONS alt where alt.MODIFIED_BY like '%System%'
Check that the Length and Bytes columns are what you expect to see.

Resources