SQL violation of primary key constraint replication - sql-server-2008

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

Related

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
'

how to insert service data in compact database in wp8

Iam caching the services using the database ,I am using sql server compact database (.sdf file) and copying database to isolated storage.There is a change in services so iam not able to cache it ,So how to manually insert services in.sdf file
CREATE TABLE [GenContents]
(
[Id] INT NOT NULL IDENTITY (1,1),
[ModuleUniqueName] NVARCHAR(4000) NOT NULL,
[ResponseContent] NTEXT,
[Category] NVARCHAR(4000) NOT NULL,
[Language] NVARCHAR(4000) NOT NULL,
[StoredTime] NVARCHAR(4000) NOT NULL
);
ALTER TABLE [GenContents] ADD CONSTRAINT [PK_GenContents] PRIMARY KEY ([Id]);

Why does this mysql routine always returns a false in phpmyadmin sql console of XAMPP?

I just reinstalled XAMPP using this installer: xampp-win32-1.8.3-2-VC11-installer. The issue below still exists. I have saved the routine, and have called it from the phpmyadmin sql console.
Environemnt: 5.6.14 - MySQL Community Server (GPL), Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6
Breakdown is as follows: Trying to insert a record only if one does not previously exist. Once the record is inserted I request for that record to be returned, else return false. In the following stored procedure below I always get a false returning, even if a new record is inserted. It's like the ELSE statement is being ignored. Why is this occurring and how can it be corrected?
DROP PROCEDURE IF EXISTS `session_initiation`//
CREATE PROCEDURE `session_initiation`(
IN _user_id bigint(20),
IN _device_id bigint(20),
IN _token varchar(255)
)
BEGIN
IF NOT EXISTS
(
SELECT (1) from active_session where token = _token
)
THEN
INSERT INTO active_session (user_id, device_id, token, datetime_create, datetime_expiry ) VALUES ( _user_id, _device_id, _token, NOW(), NOW() + INTERVAL 1 DAY );
SELECT * from active_session where token = _token;
ELSE
SELECT FALSE;
END IF;
END//
I would expect if the record does not exist, that the record would be inserted and then that same record would be returned. Instead I get the record inserted, and the following being returned:
FALSE
_____
0
Appreciate anyone that can help correct my issue. I am running this directly from the SQL tab within phpmyadmin sql console.
Here are some calls to the procedure:
call session_initiation(1,1,'abc123') //inserts and returns false = 0
call session_initiation(1,1,'123abc') //inserts and returns false = 0
call session_initiation(1,1,'abc123') //returns false = 0, does not reinsert the record.
As demo-ed by #wchiquito
The solution I provided is correct in SQL Fiddle. I made slight modifications to include an primary field, which is auto_incremented.
Here are the table details:
DROP TABLE IF EXISTS `active_session`;
CREATE TABLE IF NOT EXISTS `active_session` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`device_id` bigint(20) NOT NULL,
`token` varchar(255) DEFAULT NULL,
`datetime_create` datetime DEFAULT NULL,
`datetime_expiry` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Change:
...
IF NOT EXISTS (SELECT (1) from active_session where token = _token) THEN
...
by:
...
IF (SELECT (1) from active_session where token = _token) IS NOT NULL THEN
...
UPDATE
After creating a test SQL Fiddle the problem you describe I can not reproduce. Your code works as expected. The stored procedure does not seem to be the problem.

Compulsory Primary Key for Sql server

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