Compulsory Primary Key for Sql server - sql-server-2008

Is there any configuration setting in SQL Server 2008 for put Primary key must when create a New table ?
I know Oracle does not allow to create a Table without Primary key.But SQL Server 2008 does not having such a restriction.
Do you know any method to do so (most of the time I forget to create it and SQL Azure will give error for that)?

You could use DDL Triggers for this, and you'd have to parse Sql to check if PK is being created.
I don't think there's another option.
Example:
create trigger trgTable
on database
for create_table, alter_table
as
set nocount on
declare #data xml, #obj varchar(255), #type varchar(255), #cmd varchar(max)
set #data = EVENTDATA()
select
#obj = #data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'varchar(256)'),
#type = #data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'varchar(25)'),
#cmd = #data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'varchar(max)')
-- now do your logic here

Related

How to add id automatically in SAS

I have the following SAS code:
PROC SQL;
CREATE TABLE HUB_Addresses (
AddressID INT AUTO_INCREMENT,
LOAD_DATE NUM FORMAT=DATETIME22. NOT NULL,
RECORD_SOURCE VARCHAR(255) NOT NULL
);
RUN;
quit;
But AUTO_INCREMENT is not working. How can I fix it
You Can Add other columns and run.
CREATE TABLE `HUB_Addresses` (
`AddressID` INT NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`AddressID`))
ENGINE = MyISAM;
RDBMS features found in other systems, such as Oracle, SQL Server or Netezza:
auto_increment not in SAS SQL
triggers not in SAS SQL
default values not in SAS SQL
sequences not in SAS SQL
If your data design depends on auto_increment you will have to use a third party data base and the appropriate SAS/ACCESS engine to interact with it.
Proc SQL lacks the listed features because the default Base SAS library engine (V9) does not support such features.
If you already have a MySQL connection available and a SAS/ACCESS engine to interoperate:
SAS/ACCESS to MySQL or
SAS/ACCESS to ODBC with MySQL ODBC drivers installed
You can use pass-through syntax to submit MySQL statements directly to the data base server.
libname REMOTE MYSQL … connection options …;
PROC SQL;
connect using REMOTE;
execute (
/* MySQL statement */
CREATE TABLE HUB_Addresses (
AddressID INT AUTO_INCREMENT,
LOAD_DATE DATE NOT NULL,
RECORD_SOURCE VARCHAR(255) NOT NULL
)
by REMOTE;
* insertion occurs through SAS/ACCESS engine via REMOTE libref;
insert into REMOTE.HubAddresses
values (., '01FEB2010'D, 'Manual insert')
;

How to Create Stored Procedure in MySQL

My tables are
create table employee(
id int(10) auto_increment primary key,
name varchar(100),
addressId int(10)
);
go
create table address(
id varchar(10) auto_increment primary key,
name varchar(100)
);
Here is my procedure
create procedure insert_employee(IN emp_name varchar(100),IN emp_address varchar(100))
begin
DECLARE #addressId varchar(10);
SELECT #addressId:=id from address where name LIKE '%'+emp_address+'%';
IF #addressId = ''
THEN
set #addressId= 'DBS-2136';-- It will come form function
INSERT INTO address values(#addressId,emp_address);
END IF
INSERT INTO employee values(emp_name,#addressId);
END
I don't understand what is the problem. If i write this type of if condition in ms sql server there is not error. every time execute the procedure ti say error in end if. I have search in google but there is not idea about this. there is a problem in declare variable. If i copy form mysql documentation that also not work. why is that?
please help me
1. What is the proper way to declare variable under mysql stored procedure,
2. how to write if condition in mysql stored procedure.
thank you
Lots of differences between mysql and mssql. Declared variables should not include '#', all statements must be terminated, + is an arithmetic operator, if you procedure has multiple statements you must set delimiters before and after.
Further reading
How to declare a variable in MySQL?
https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
From MySQL reference Manual
An IF ... END IF block, like all other flow-control blocks used within stored programs, must be terminated with a semicolon
IF #addressId = ''
THEN
set #addressId= 'DBS-2136';-- It will come form function
INSERT INTO address values(#addressId,emp_address);
END IF;

Why won't my SQL passwordhashing-procedure run?

I am trying to create a SQL procedure that hashes password inputs. This code won't run and I am not getting any useful response errors.
The first part creates the table, the second creates the procedure. When I call on my procedure in the third part it send the values into the procedure. There the password is supposed to be hashed using SHA2_512 and inserted into the table we made eralier.
I used online research to make this code, the parts I don't get is:
The N before my values
The SetNoCount
The #responsemessage
-- makes Admin table
CREATE TABLE IF NOT EXISTS `AdminUser` (
`AdminID` smallint(6) NOT NULL AUTO_INCREMENT,
`Username` char(15) NOT NULL,
`PasswordHash` BINARY(64) NOT NULL,
`Fornavn` char(30) NOT NULL,
`Etternavn` char(40) NOT NULL,
`Email` char(40) NOT NULL,
PRIMARY KEY (`AdminID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Makes hashing procedure
CREATE OR REPLACE PROCEDURE vm_ski.addAdmin
#pUsername NVARCHAR(50),
#pPassword NVARCHAR(50),
#pFornavn NVARCHAR(30),
#pEtternavn NVARCHAR(40),
#pEmail NVARCHAR(40),
#responseMessage NVARCHAR(250)='' OUTPUT
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
INSERT INTO vm_ski.AdminUser (Username, PasswordHash, Fornavn, Etternavn, Email)
VALUES(#pUsername, HASHBYTES('SHA2_512', #pPassword), #pFornavn, #pEtternavn, #pEmail)
SET #responseMessage='Success'
END TRY
BEGIN CATCH
SET #responseMessage=ERROR_MESSAGE()
END CATCH
END;
-- Admin example
DECLARE #responseMessage NVARCHAR(250)
EXECUTE vm_ski.addAdmin
#pUsername = N'sondre',
#pPassword = N'example'
#pFornavn = N'Sondre'
#pEtternavn = N'Morgendal'
#pEmail = N'sondre.example#gmail.com'
;
This is not a direct answer to the question; this is a security note on the methodology of the question
Do NOT hash passwords in MySQL. The data given to MySQL is plaintext, and easily intercepted by MySQL processing logs as well as possibly numerous other places before being dumped in the database (such as if message packets sent to the database are non-localhost and are non-TLS). ( Why? )
When hashing passwords you want to be doing so as early in the process as possible. This typically means using PHP password_hash and simply dumping only the hashed data in the MySQL.
If you do not use PHP to interact with your SQL then you can use other server methods such as Argon2 or Libsodium.
Also as a side point you should be using the mb4 UTF-8 charset and collations - principly utf8mb4_general_ci ( Why? )

Deploy Sql Changes to Customer Databases (altered tables, functions,...)

I am developing an application that uses a database (either PostgreSQL, MySQL, Oracle or MSSQL) on the customers system.
Therefore I need to perform database updates with each new version.
I am currently in the concept phase and have nothing running in production.
All the DDL statements are in script files.
The structure looks like this:
tables\employees.sql
customers.sql
orders.sql
Those scripts are also in version control and can be used to build the database from stretch.
Of course there will be changes sometime in the future to those tables.
For example table employees gets created like this:
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName text,
PRIMARY KEY (EmployeeId)
);
And in a future release that table gets extended:
ALTER TABLE employees ADD COLUMN address varchar(30);
On my research I found this example: https://stackoverflow.com/posts/115422/revisions.
A version number gets used to perform specific changes.
I like that concept and my idea is to implement something similar.
But instead of a system version number I was thinking about introducing a version for each table.
When creating the employee table it gets the Version number 1. With each change on that table the version number get increased by 1. After adding the address column (alter statement above) the table version would be 2.
Each table change would happen in a nested transaction like this:
BEGIN TRANSACTION;
UPDATE employees SET Version = 2;
ALTER TABLE employees
ALTER TABLE employees ADD COLUMN address varchar(30);
END TRANSACTION;
If the table version is lower than the current table version the transaction would be rolled back.
The implentation of that logic is yet to be done.
The benefit would be that all changes on a table are inside the table's script file itself and the initial statement is always up to date.
For example when first creating the employee table it would look like this:
employees.sql
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName text,
Version int default 1 not null,
PRIMARY KEY (EmployeeId)
);
After some changes it looks like this:
employees.sql
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName varchar(100),
address varchar(80),
Version int default 3 not null, -- notice the 3
PRIMARY KEY (EmployeeId)
);
-- First Change
BEGIN TRANSACTION;
UPDATE employees SET Version = 2;
ALTER TABLE employees
ALTER TABLE employees ADD COLUMN address varchar(30);
END TRANSACTION;
-- Second Change
BEGIN TRANSACTION;
UPDATE employees SET Version = 3;
ALTER TABLE employees
ALTER COLUMN address TYPE varchar(80),
ALTER COLUMN FirstName TYPE varchar(100);
END TRANSACTION;
Is that concept acceptable or am I reinventing the wheel here?
I think setting the version number per table is overkill. Also, it complicates managing the DB and the application. I suggest you add a new table for DB_VersionNumber and add one row in this table for each upgrade. What I have been doing is this:
1) Create a table in DB for database versions (steps)
2) Create a SP that checks this table and runs a DB upgrade step if it does not exist in the table, otherwise the step is skipped.
3) For each and every DB change, add a step in the upgrade script file (which you have already created and added to the source control).
Here is the table and the SP:
IF OBJECT_ID (N'DB_Version', N'U') IS NULL
Begin
CREATE TABLE [DB_Version](
[VersionNumber] [decimal](18, 2) NOT NULL,
[CommitTimestamp] [smalldatetime] NOT NULL
) ON [PRIMARY]
ALTER TABLE DB_Version
ADD CONSTRAINT UQ_VersionNumber UNIQUE (VersionNumber);
End
IF OBJECT_ID ( 'NewDBStep', 'P' ) IS NULL
begin
Exec ('
-- ============================================
-- Description: Applies a new DB upgrade step to the current DB
-- =============================================
CREATE PROCEDURE NewDBStep
#dbVersion [decimal](18, 2),
#script varchar (max)
AS
BEGIN
If not exists (select 1 from DB_Version Where VersionNumber = #dbVersion)
Begin
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN TRY
Begin tran
Exec (#script)
Insert into DB_Version (VersionNumber, CommitTimestamp) Values (#dbVersion, CURRENT_TIMESTAMP);
Commit tran
Print ''Applied upgrade step '' + Cast ( #dbVersion as nvarchar(20))
END TRY
BEGIN CATCH
Rollback tran
Print ''Failed to apply step '' + Cast ( #dbVersion as nvarchar(20))
Select ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
End
END ') ;
End
Then, apply your upgrades by calling the SP (the key is that you have to assign a unique step number to each upgrade script:
---------------- Add the new steps here
-- Step: 0.01
-- Adding the MyTableName table if it does not exist.
Exec NewDBStep 0.01, '
IF OBJECT_ID (N''MyTableName'', N''U'') IS NULL
Begin
CREATE TABLE [MyTableName](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserType] [nvarchar](20) 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]
End
'
Exec NewDBStep 1.00, '
-- Some other DDL script
'

SQL violation of primary key constraint replication

I'm trying to make a replication between an sql server 2008 to 2012
I have done that before between 2008 server and works perfectly
Now when I set the publication type to snapshot, and doing it as a push from the distributor to the subscriber I'm getting an error
Violation of PRIMARY KEY constraint 'PK__tableF__4EBD61D204E4BC85'. Cannot insert duplicate key in object 'dbo.table'. The duplicate key value is (0). (Source : MSSQLServer, Numéro d'erreur : 2627)
Obtenir de l'aide : http://help/2627
Even if I selected only one table to replicate I had always the same problem, the schema of the database is created but no data in the table
I tried to ressed the table and it doesn't work.
Please what can I do?
Thanks
I'm always with this problem
I tried to write a script instead of using the wisard
DECLARE #publication AS sysname;
DECLARE #subscriber AS sysname;
DECLARE #subscriptionDB AS sysname;
DECLARE #frequency_type as int;
DECLARE #subscriber_security_mode as int;
DECLARE #subscriber_login AS sysname;
DECLARE #subscriber_password AS sysname;
SET #publication = N'8-9' ;
SET #subscriber =N'APPLI-SERV-EXT';
SET #subscriptionDB = N'89' ;
SET #subscriber_security_mode= 1;
SET #subscriber_login=N'xxx';
SET #subscriber_password=N'xxxx';
--Add a push subscription to a transactional publication.
USE [DBName]
EXEC sp_addsubscription
#publication = #publication,
#subscriber = #subscriber,
#destination_db = #subscriptionDB,
#subscription_type = N'push';
EXEC sp_addpushsubscription_agent
#publication = #publication,
#subscriber = #subscriber,
#subscriber_db = #subscriptionDB,
#subscriber_security_mode=#subscriber_security_mode,
#subscriber_login=#subscriber_login,
#subscriber_password=#subscriber_password,
#frequency_type = #frequency_type,
#job_login = N'xxxx',
#job_password = N'xxx';
GO
when I execute I got a warning "Warning : the work of the distribution agent Was implicitly created and will run under the service account of the SQL Server Agent."
If I check the subscriber I found that the schema is replicated and instead to have a 418 row in the table I have 4012 and the table is empty except a not null attribute which is 0
here is the script of the table
USE [test]
GO
/****** Object: Table [dbo].[clientEssai] Script Date: 15/09/2015 15:13:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[clientEssai](
[client_id] [int] NOT NULL,
[client_name] [varchar](255) NULL,
[contact_name] [varchar](255) NULL,
[tel] [varchar](255) NULL,
[gsm] [varchar](255) NULL,
[email] [varchar](255) NULL,
[adress] [varchar](255) NULL,
[registration_date] [date] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
P.S: I selected only one article to replicate which is the table ClientEssai
Publisher and Distributor are the 2008 instance
subscriber 2012
I'm doing a push
and I'm using the same account for the agents
Is there a particular configuration to do?
Thank you