Combine two columns and input the result in a different columns using SQL server - sql-server

Please can anyone help me with the insert sql statement below. I am trying to create a SampleID by combining column ID (auto generate by the database) and the MBID column. I am having the error 'CONCAT' is not a recognized built-in function name.
Thanks
SqlCommand sc = new SqlCommand(#"insert into Sample (MBID, SampleType,SampleDate,ConsultantName,Comments,FirstSample, SampleID)
values(#MBID , #SampleType , #SampleDate , #ConsultantName , #Comments, CONCAT(ID +'-'+ MBID) ;", con);
Table Design
CREATE TABLE [dbo].[Sample] (
[ID] INT IDENTITY (5, 1) NOT NULL,
[SampleID] NVARCHAR (50) NOT NULL,
[SampleType] NVARCHAR (50) NULL,
[SampleDate] DATE NULL,
[ConsultantName] NVARCHAR (50) NULL,
[Comments] NVARCHAR (MAX) NULL,
[FirstSample] NVARCHAR (MAX) NULL,
[MBID] INT NULL,
CONSTRAINT [PK_Sample] PRIMARY KEY CLUSTERED ([SampleID] ASC)
);

Firstly, CONCAT was introduced in SQL Server 2012
Using CONCAT function:
SELECT CONCAT ( 'Welcome ', 'World ', '!' ) AS Result;
Secondly, you want auto generated value to be concatenated to the id value for the sample Id column. The below query can be used for that...
SELECT IDENT_CURRENT('table_name')+1;
Now, alter your query as below
SqlCommand sc = new SqlCommand(#"insert into Sample (MBID, SampleType,SampleDate,ConsultantName,Comments,FirstSample, SampleID)
values(#MBID , #SampleType , #SampleDate , #ConsultantName , #Comments, cast((IDENT_CURRENT('Sample')+1) as VARCHAR(max)) +'-'+ CAST(#MBID AS VARCHAR(10)));", con);

CONCAT is available from SQLServer 2012..use + instead
Also remeber ,you might have to use ISNULL to avoid nulls,Since CONCAT ignores nulls

To concatenate strings in SQL-server, you could either use the CONCAT function, or +. You are trying to do both.
The CONCAT function takes at least 2 comma-separated arguments.
So, either
ID +'-'+ MBID
Or
CONCAT(ID, '-', MBID)

Related

Perl, SQL Server use of ##IDENTITY

I have a SQL Server table with an identity column, set to autoincrement.
Coded in Perl, the insert in the code below works fine, in the while loop the fetchrow_array() call returns no data in the #row array.
How do I best retrieve the identity value for use in subsequent SQL statements?
my $term_sql = "INSERT INTO reminder_term(site, name, description, localization) OUTPUT \#\#IDENTITY VALUES(?,?,?,?)";
my $t_stmt = $dbh->prepare($term_sql);
...
$t_stmt->execute($site, $name, $description, $localizer);
while (#row = $t_stmt->fetchrow_array()) {
$referential_key = $row[0];
}
Avoid using the ##IDENTITY value since it's unreliable in the presence of triggers.
Given the example table schema...
create table [dbo].[reminder_term] (
[id] int not null identity(1,1),
[site] nvarchar(10),
[name] nvarchar(10),
[description] nvarchar(10),
[localization] nvarchar(10)
);
You can rework your OUTPUT clause slightly you can capture the new id value by way of the special inserted row source...
INSERT INTO reminder_term(site, name, description, localization)
OUTPUT inserted.id
VALUES(?,?,?,?)

How to use MERGE-statement with VARBINARY data

I'm stuck trying to figure out how to get one of the MERGE statements to work. See below code snippet:
DECLARE #PipelineRunID VARCHAR(100) = 'testestestestest'
MERGE [TGT].[AW_Production_Culture] as [Target]
USING [SRC].[AW_Production_Culture] as [Source]
ON [Target].[MD5Key] = [Source].[MD5Key]
WHEN MATCHED AND [Target].[MD5Others] != [Source].[MD5Others]
THEN UPDATE SET
[Target].[CultureID] = [Source].[CultureID]
,[Target].[ModifiedDate] = [Source].[ModifiedDate]
,[Target].[Name] = [Source].[Name]
,[Target].[MD5Others] = [Source].[MD5Others]
,[Target].[PipelineRunID] = #PipelineRunID
WHEN NOT MATCHED BY TARGET THEN
INSERT VALUES (
[Source].[AW_Production_CultureKey]
,[Source].[CultureID]
,[Source].[ModifiedDate]
,[Source].[Name]
,#PipelineRunID
,[Source].[MD5Key]
,[Source].[MD5Others]);
When I try and run this query I receive the following error:
Msg 257, Level 16, State 3, Line 16
Implicit conversion from data type varchar to varbinary is not allowed. Use the CONVERT function to run this query.
The only VARBINARY column types are MD5Key and MD5Others. As they are both linked to their corresponding columns I don't understand why my error message indicates there is a VARCHAR problem involved. Does anybody understand how and why I should use a CONVERT() function here?
Thanks!
--EDIT: Schema definitions
CREATE VIEW [SRC].[AW_Production_Culture]
WITH SCHEMABINDING
as
SELECT
CAST(CONCAT('',[CultureID]) as VARCHAR(100)) as [AW_Production_CultureKey]
,CAST(HASHBYTES('MD5',CONCAT('',[CultureID])) as VARBINARY(16)) as [MD5Key]
,CAST(HASHBYTES('MD5',CONCAT([ModifiedDate],'|',[Name])) as VARBINARY(16)) as [MD5Others]
,[CultureID],[ModifiedDate],[Name]
FROM
[SRC].[tbl_AW_Production_Culture]
CREATE TABLE [TGT].[AW_Production_Culture](
[AW_Production_CultureKey] [varchar](100) NOT NULL,
[CultureID] [nchar](6) NULL,
[ModifiedDate] [datetime] NULL,
[Name] [nvarchar](50) NULL,
[MD5Key] [varbinary](16) NOT NULL,
[MD5Others] [varbinary](16) NOT NULL,
[RecordValidFrom] [datetime2](7) GENERATED ALWAYS AS ROW START NOT NULL,
[RecordValidUntil] [datetime2](7) GENERATED ALWAYS AS ROW END NOT NULL,
[PipelineRunID] [varchar](36) NOT NULL,
PRIMARY KEY CLUSTERED
(
[MD5Key] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY],
PERIOD FOR SYSTEM_TIME ([RecordValidFrom], [RecordValidUntil])
) ON [PRIMARY]
WITH
(
SYSTEM_VERSIONING = ON ( HISTORY_TABLE = [TGT].[AW_Production_Culture_History] )
)
Reposting my comment as an answer for the sweet, sweet, internet points:
You're getting that error because your varbinary value is being inserted into a varchar column. As your columns have the correct types already then it means your INSERT clause has mismatched columns.
As it is, your MERGE statement is not explicitly listing the destination columns - you should always explicitly list columns in production code so that your DML queries won't break if columns are added or reordered or marked HIDDEN.
So to fix this, change your INSERT clause to explicitly list destination column names.
Also, when using MERGE you should use HOLDLOCK (Or a more suitable lock, if applicable) - otherwise you’ll run into concurrency issues. MERGE is not concurrency-safe by default!
Minor nit-picks that are largely subjective:
I personally prefer avoiding [escapedName] wherever possible and prefer using short table aliases.
e.g. use s and t instead of [Source] and [Target].
"Id" (for "identity" or "identifier") is an abbreviation, not an acronym - so it should be cased as Id and not ID.
Consider using an OUTPUT clause to help diagnose/debug issues too.
So I'd write it like so:
DECLARE #PipelineRunId VARCHAR(100) = 'testestestestest'
MERGE INTO
tgt.AW_Production_Culture WITH (HOLDLOCK) AS t
USING
src.AW_Production_Culture AS s ON t.MD5Key = s.MD5Key
WHEN MATCHED AND t.MD5Others != s.MD5Others THEN UPDATE SET
t.CultureId = s.CultureId,
t.ModifiedDate = s.ModifiedDate,
t.Name = s.Name,
t.MD5Others = s.MD5Others,
t.PipelineRunID = #PipelineRunId
WHEN NOT MATCHED BY TARGET THEN INSERT
(
AW_Production_CultureKey,
CultureId,
ModifiedDate,
[Name],
PipelineRunId,
MD5Key,
MD5Others
)
VALUES
(
s.AW_Production_CultureKey,
s.CultureId,
s.ModifiedDate,
s.[Name],
#PipelineRunId,
s.MD5Key,
s.MD5Others
)
OUTPUT
$action AS [Action],
inserted.*,
deleted.*;

Create table from query result

I do have a problem with creating proper SQL statement.
Scenario, i do have a table "Excel" which is populated by SQLBulkCopy few times, after that table contains duplicates which I want to sum by "Buildneed", I have figured out way to return "consolidated" result with below query :
SELECT GBC, Description, sum(Buildneed) as Buildneed, Replaced
FROM Excel
GROUP BY GBC, Description, Replaced
ORDER BY GBC ASC
Now I would like to drop NewTable if exists, create NewTable again and populate this table from mentioned above result.
So I wrote this statement :
DROP TABLE IF EXISTS dbo.NewTable
CREATE TABLE [dbo].[NewTable]
(
[GBC] INT NULL,
[Description] VARCHAR (80) NULL,
[Buildneed] INT NULL,
[Replaced] VARCHAR (80) NULL
);
SELECT Excel2.GBC, Excel2.Description, Excel2.Buildneed, Excel2.Replaced
INTO NewTable
FROM (SELECT GBC, Description, sum(Buildneed) as Buildneed, Replaced
FROM Excel
GROUP BY GBC, Description, Replaced
ORDER BY GBC ASC) AS Excel2
I'm not receiving any error information, table is not created after running above query.
Every single time new data will come to table "Excel" I want to "consolidate -> drop NewTable -> create NewTable with new data"
Sample data :
CREATE TABLE [dbo].[Excel]
(
[GBC] INT NULL,
[Description] VARCHAR (80) NULL,
[Buildneed] INT NULL,
[Replaced] VARCHAR (80) NULL
);
INSERT INTO #Excel (GBC, [Description], Buildneed, Replaced)
SELECT 71744, 'RES_TF,10k,0402,1%,0,1W,100PPM/C', 2000
UNION ALL
SELECT 71744, 'RES_TF,10k,0402,1%,0,1W,100PPM/C', 1000
UNION ALL
SELECT 76527, 'CAP_CER,10nF,0402,10%,50V,X7R', 288
UNION ALL
SELECT 86911, 'CAP_CER,10nF,0603,10%,100V,X7R', 1464
Expected result -> New table created with name "NewTable"
GBC / Description / Buildneed / Replaced
71744 / RES_TF,10k,0402,1%,0,1W,100PPM/C / **3000** / null
76527 / CAP_CER,10nF,0402,10%,50V,X7R / 288 / null
86911 / CAP_CER,10nF,0603,10%,100V,X7R / 1463 / null
First of all, I suggest to create the new table with another name, drop the old table after the new table has successfully been created and then rename the new table to the desired name - so you prevent data loss in case anything doesn't work during table creation. Furthermore the SELECT ... INTO should create a new table without the need of creating it first. Another possibility would be INSERT INTO... SELECT...
Here an example:
CREATE TABLE [dbo].[Excel] (
[GBC] INT NULL,
[Description] VARCHAR (80) NULL,
[Buildneed] INT NULL,
[Replaced] VARCHAR (80) NULL
);
insert into [Excel] (GBC, [Description], Buildneed, Replaced)
select 71744, 'RES_TF,10k,0402,1%,0,1W,100PPM/C' ,2000, NULL
union all
select 71744, 'RES_TF,10k,0402,1%,0,1W,100PPM/C' ,1000, NULL
union all
select 76527, 'CAP_CER,10nF,0402,10%,50V,X7R' ,288, NULL
union all
select 86911, 'CAP_CER,10nF,0603,10%,100V,X7R' ,1464, NULL;
SELECT Excel2.GBC, Excel2.Description, Excel2.Buildneed, Excel2.Replaced
INTO NewTable
FROM (SELECT GBC, Description, sum(Buildneed) as Buildneed, Replaced FROM Excel GROUP BY GBC, Description, Replaced) as Excel2;
SELECT *
FROM NewTable
See SQL Fiddle for an example: sqlfiddle.com/#!18/d568e/5/2

How to store Arabic in SQL server?

I am trying to store Arabic-strings in my database. it is working fine by using COLLATE Arabic_CI_AI_KS_WS but some of Arabic records are missing some Arabic-alphabets. i have tried with some other sollate with but result as same. how to fix it ?
table structure :
CREATE TABLE [dbo].[Ayyat_Translation_Language_old_20131209] (
[Ayat_Translation_Language_ID] INT IDENTITY (1, 1) NOT NULL,
[Translation_Laanguage_ID] INT NULL,
[Juz_ID] INT NULL,
[Surah_ID] INT NOT NULL,
[Ayat_Description] VARCHAR (2000) COLLATE Arabic_CI_AI_KS_WS NOT NULL
)
insertion code :
string query = "insert into Ayyat_Translation_Language_old_20131209 values(null,null," + surah + ",N'" + verse + "')"; where verse contains Arabic contents.
and it stores data like this (with question-marks) :
?بِسْمِ اللَّهِ الرَّحْمَ?نِ الرَّحِيمِ
i have read that link : store arabic in SQL database
To store unicode string data, use NVARCHAR(2000) rather than VARCHAR(2000) for column [Ayat_Description]
Ref.: nchar and nvarchar
All of what you have to do is to make sure that
the column Data type is nvarchar()
after that I inserted Arabic with no problems even with Tashkeel
this in SQl server management studio 2012
It may help
CREATE TABLE [dbo].[Ayyat_Translation_Language_old_20131209] (
[Ayat_Translation_Language_ID] INT IDENTITY (1, 1) NOT NULL,
[Translation_Laanguage_ID] INT NULL,
[Juz_ID] INT NULL,
[Surah_ID] INT NOT NULL,
[Ayat_Description] NVARCHAR (2000) COLLATE Arabic_CI_AI_KS_WS NOT NULL
use arabic collation or use unicode(nvarchar(max))
This is a Example table For your answer :
CREATE TABLE #t11
(
column1 NVARCHAR(100)
)
INSERT INTO #t11 VALUES(N'لا أتكلم العربية')
SELECT * FROM #t11
fiddle demo

Create column with Year and autoincrement

i want to know if is possible to create a table with a Column which got a autoincrement with the number of the year in front if ( Format: YYYY## ):
CRATE TABLE "Example"(
[Number] autoincrement(YYYY##),
[Text] nvarchar(30)
)
how has the column 'number' to look like? ist it even possible?
thanks!
Part 2:
The number behind the year should start from 0 after every year.
Example output:
2013-01
2013-02
2013-03
2014-01
You can use Computed Columns
For example:
CREATE TABLE T
(
ID int IDENTITY (1,1) NOT NULL,
DateField datetime DEFAULT (getdate()),
DateIDChar AS CAST(YEAR(DateField) AS Varchar)+'-'+CAST(ID as VARCHAR),
DateIDInt AS YEAR(DateField) * 10000+ID,
SampleField varchar(100)
);
SQLFiddle demo
Here:
ID is a base autoincremented field
DateField is a DateTime part with current date as default
DateIDChar - example computed field formatted as a varchar
DateIDId - example computed field formatted as a int
As far as I know, you cannot do this with the autoincrement column. You could, instead, have an additional column with the day of creation of the record. Then, when you want to output the column with the autoincrement, you can format the output according to your especifications.
i.e.
CREATE TABLE "Example" (
[Number] autoincrement(YYYY##),
[Text] nvarchar(30),
[CreatedDate] datetime
)
-- output
select convert(varchar(4), year(CreatedDate)) + convert(varchar, Number)
Hope this helps

Resources