Id auto increment varchar not increments - sql-server

I am using a VARCHAR column as my primary key. I want to auto increment it (base 62, lower/upper case, numbers), However, the below code fails (for obvious reasons):
CREATE TABLE TESTING
(
ID VARCHAR(10),
NAME VARCHAR(15),
DESCP VARCHAR(50)
);
Creating a procedure for testing insert of a new record with NVARCHAR auto-incremented ID:
CREATE PROCEDURE SP_INSERT
#NAME VARCHAR(MAX), #DESCP VARCHAR(MAX)
AS
BEGIN
/* Logic for getting new ID as per the NAME with PRE FIX */
DECLARE #NEWID VARCHAR(5);
DECLARE #PREFIX VARCHAR(10);
SET #PREFIX = UPPER(SUBSTRING('STR', 1, 3))
SELECT #NEWID = (#PREFIX + replicate('0', 3 - len(CONVERT(VARCHAR, N.OID 1))) + CONVERT(VARCHAR, N.OID + 1))
FROM
(SELECT
CASE
WHEN MAX(T.TID) IS NULL
THEN 0 ELSE MAX(T.TID)
END AS OID
FROM
(SELECT SUBSTRING(ID, 1, 1) AS PRE_FIX,
SUBSTRING(ID, 2, LEN(ID)) AS TID
FROM Testing) AS T
WHERE
T.PRE_FIX = #PREFIX) AS N
/* INSERT QUERY FOR NEW RECORD */
INSERT INTO Testing VALUES (#NEWID, #NAME, #DESCP)
END
I try to insert a values:
SP_INSERT 'svce','YOUR MANAGEMENT DESCRIPTION';
this first time, again try to inset I got same ID is not incremented.
Like:
ID Name
------------
SVC001 SVCE
SVC001 Svce

You could try to use COMPUTED COLUMN something like that:
create table t
(
Id int auto_increment,
ComputedId as 'SVC' + convert(nvarchar(60), lpad(Id,3,'0')),
Data nvarchar(60)
)

I MADE ONE SMALL SCRIPT,
declare #t table (id varchar(10))
insert into #t values ('SVC001'),('SVC20902')
Declare #NEWID int
select #NEWID=isnull(max(replace(id,'SVC',''))+1,1) from #t
select 'SVC'+ replicate('0',CASE WHEN 3-len(#NEWID)<=0
THEN 0 ELSE 3-len(#NEWID) END)+cast(#NEWID as varchar(10))

Finally I got solution for Auto_Increment ID. I done following code for solution. code is:
alter PROCEDURE SP2_INSERT
#NAME VARCHAR(MAX),
#DESCP VARCHAR(MAX)
AS
BEGIN
DECLARE #NEWID VARCHAR(10);
DECLARE #PREFIX VARCHAR(MAX);
SET #PREFIX = UPPER(SUBSTRING(#NAME,1, 3))
SELECT #NEWID = (#PREFIX + replicate('0', 3 - len(CONVERT(VARCHAR,N.OID + 1))) + CONVERT(VARCHAR,N.OID + 1)) FROM (
SELECT CASE WHEN MAX(T.TID) IS null then 0 else MAX(T.TID) end as OID FROM (
SELECT SUBSTRING(EmployeeID, 1, 1) as PRE_FIX,SUBSTRING(EmployeeID, 2, LEN(EmployeeID)) as TID FROM EmployeeMasters
) AS T WHERE T.PRE_FIX = #PREFIX
) AS N
INSERT INTO Testing VALUES (#NEWID,#NAME,#DESCP)
end

Try this,
DECLARE #table TABLE(ID VARCHAR(10),
NAME VARCHAR(15),
DESCP VARCHAR(50))
DECLARE #NEWID VARCHAR(5);
DECLARE #PREFIX VARCHAR(10);
SET #PREFIX = UPPER(SUBSTRING('STR', 1, 3))
SELECT #NEWID=CAST(ISNULL(MAX(CAST(SUBSTRING(ID,4,LEN(ID)) AS INT)),0)+1 AS varchar) FROM #table
INSERT INTO #table(DESCP,ID,NAME)
SELECT 'zzzz',(#PREFIX + replicate('0', 3 - len(CONVERT(VARCHAR,#NEWID))))+#NEWID,'fsf'
SELECT #NEWID=CAST(ISNULL(MAX(CAST(SUBSTRING(ID,4,LEN(ID)) AS INT)),0)+1 AS varchar) FROM #table
INSERT INTO #table(DESCP,ID,NAME)
SELECT 'zzzz',(#PREFIX + replicate('0', 3 - len(CONVERT(VARCHAR,#NEWID))))+#NEWID,'fsf'
SELECT * FROM #table

Related

Have this problem with calling stored procedure unknown object type

I am trying to write a query that needs to call a stored procedure. But it always throws an error:
Unknown object type 'TABLEIXICHistoricalData' used in a CREATE, DROP, or ALTER statement.
This is query:
USE ETLCourse
DECLARE #LOOP TABLE
(
ID INT IDENTITY(1,1),
TableName NVARCHAR(100)
)
INSERT INTO #LOOP (TableName)
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%_Stocks%'
DECLARE #b INT = 1, #m INT, #t NVARCHAR(100)
SELECT #m = MAX(ID) FROM #LOOP
WHILE #b <= #m
BEGIN
SELECT #t = TableName
FROM #LOOP
WHERE ID = #b
EXECUTE [dbo].[stp_BuildNormalizedTable] #t
SET #b = #b + 1
END
and here is the procedure:
ALTER PROCEDURE [dbo].[stp_BuildNormalizedTable]
#table NVARCHAR(100)
AS
BEGIN
DECLARE #cleanTable NVARCHAR(100),
#s NVARCHAR(MAX)
SET #cleanTable = REPLACE(#table, '_Stocks', 'HistoricalData')
SET #s = 'CREATE TABLE' + #cleanTable + '(ID INT IDENTITY(1,1), Price DECIMAL(13, 4), PriceDate DATE)
INSERT INTO' + #cleanTable + '(Price,PriceDate) SELECT [Adj Close],[Date] FROM'
+ #table + ' ORDER BY Date ASC'
--PRINT #s
EXECUTE sp_executesql #s
END
It should copy two specific column and create a new table by using #Loop table and procedure
You need to add 'space' after 'create table' and 'insert into' and 'from'
declare #s nvarchar(max)
declare #cleantable nvarchar(100)
declare #table nvarchar(100)
set #cleantable = 'aaa'
set #table = 'bbb'
SET #s = 'CREATE TABLE' + #cleanTable + '(ID INT IDENTITY(1,1),Price Decimal(13,4),PriceDate DATE)
Insert into' + #cleanTable
+ '(Price,PriceDate) SELECT [Adj Close],[Date] FROM'
+ #table + ' ORDER BY Date ASC'
print #s
Output:
CREATE TABLEaaa(ID INT IDENTITY(1,1),Price Decimal(13,4),PriceDate DATE)
Insert intoaaa(Price,PriceDate) SELECT [Adj Close],[Date] FROMbbb ORDER BY Date ASC
Use 'print' to check your query.

SQL Insert with a dynamic Column name

I have a temp table that has all the Names of Column for now there are 4 of them and I am looping through the temp table and do a Insert into another table, Now the issue is that the Column name that I want to insert depends on what it gets from the loop:
Here is the code:
Declare #OutputTable table
(
RowID int IDENTITY(1, 1),
ClientID int,
ClientName VarChar(100),
ScoreModule1 VarChar(100),
ScoreModule2 VarChar(100),
ScoreModule3 VarChar(100),
ScoreModule4 VarChar(100)
)
Declare #TempModuleNumber table
(
RowIDNumber int IDENTITY(1, 1),
ModuleNumber varchar (300)
)
INSERT INTO #TempModuleNumber(ModuleNumber)
VALUES ('ScoreModule1'), ('ScoreModule2'),
('ScoreModule3'), ('ScoreModule4')
Declare #ModuleRowCountNumber int
Declare #ModuleCounterNumber int
Declare #ModuleNumber varchar(300)
Select #ModuleRowCount = COUNT(#ModuleNumber)
from #TempModuleNumber
set #ModuleCounterNumber = 1
while #ModuleCounterNumber <= #ModuleRowCount
begin
Select #ModuleNumber = ModuleNumber
from #TempModuleNumber
where RowIDNumber = #ModuleCounterNumber
Insert into #OutputTable (ClientID, ClientName, #ModuleNumber) --This is where the problem is the #ModuleNumber is. I get a "syntax error". Is there another way of doing this to it depends on what it gets from the Loop?
Set #ModuleCounterNumber = #ModuleCounterNumber + 1
END
I only made change to the necessary part:
while #ModuleCounterNumber <= #ModuleRowCount
begin
Select #ModuleNumber = ModuleNumber
from #TempModuleNumber
where RowIDNumber = #ModuleCounterNumber
DECLARE #SQL VARCHAR(MAX)
SET #SQL =
'
Insert into #OutputTable (ClientID, ClientName, ' + #ModuleNumber + ')
SELECT A,B,C //<----------- THIS IS THE MISSING PART I WAS TALKING ABOUT
'
EXEC(#SQL)
Set #ModuleCounterNumber = #ModuleCounterNumber + 1
END

Get Float value with Comma separtor

Am new to Sql server ce. my table have float value. I want select float with comma separated and decimal position. like this
table name table1
val
1220333
222
36535
I want result like this
val
12,20,333.00
222.00
36,535.00
like indian Rupees
Am using Sql server ce 3.5
DECLARE #Table1 TABLE
(val int)
;
INSERT INTO #Table1
(val)
VALUES
(1220333),
(222),
(36535)
;
select convert(varchar(50), CAST(val as money), -1) amount from #Table1
select FORMAT(CAST(val AS MONEY),'N','en-in') amount from #Table1
OR
Function
create function to_indian_currency(#n decimal(25,5))
returns varchar(100) as
BEGIN
declare #a varchar(100) = cast(#n as varchar(100))
declare #dec_part varchar(100) =
(select substring(#a, charindex('.',#a), len(#a)-charindex('.',#a)+1))
declare #int_part varchar(100) = (select left(#a, charindex('.',#a)-1))
declare #f int = cast(#int_part as bigint)%1000
declare #q int = cast(#int_part as bigint)/1000
declare #final varchar(100) = ''
while #q > 0
begin
set #final = cast(#q%100 as varchar) + ',' + #final
set #q = #q/100
end
RETURN #final + cast(#f as varchar) + #dec_part
END
select dbo.to_indian_currency(val) from #Table1

Conversion failed when converting the varchar value to data type int in sql

I wrote the store procedure which should return the values like-
J1
J2
J3
I have table named Journal_Entry. When the row count of the table is 0, it gives the result J1 but as the row count increases it shows the error-
"Conversion failed when converting the varchar value 'J' to data type int."
#here the Voucher_No is the column for the result to be saved.
The code is like-
CREATE PROC [dbo].[getVoucherNo]
AS
BEGIN
DECLARE #Prefix VARCHAR(10)='J'
DECLARE #startFrom INT=1
DECLARE #maxCode VARCHAR(100)
DECLARE #sCode INT
IF((SELECT COUNT(*) FROM dbo.Journal_Entry) > 0)
BEGIN
SELECT #maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(#startFrom)+1,LEN(Voucher_No)- LEN(#Prefix)) AS INT)) AS varchar(100)) FROM dbo.Journal_Entry;
SET #sCode=CAST(#maxCode AS INT)
SELECT #Prefix + LEN(CAST(#maxCode AS VARCHAR(10))+1) + CAST(#maxCode AS VARCHAR(100))
END
ELSE
BEGIN
SELECT(#Prefix + CAST(#startFrom AS VARCHAR))
END
END
The problem located on the following line
SELECT #Prefix + LEN(CAST(#maxCode AS VARCHAR(10))+1) + CAST(#maxCode AS VARCHAR(100))
Use this instead
SELECT #Prefix + CAST(LEN(CAST(#maxCode AS VARCHAR(10))+1) AS VARCHAR(100)) + CAST(#maxCode AS VARCHAR(100))
Full Code:
CREATE PROC [dbo].[getVoucherNo]
AS
BEGIN
DECLARE #Prefix VARCHAR(10)='J'
DECLARE #startFrom INT=1
DECLARE #maxCode VARCHAR(100)
DECLARE #sCode INT
IF((SELECT COUNT(*) FROM dbo.Journal_Entry) > 0)
BEGIN
SELECT #maxCode = CAST(MAX(CAST(SUBSTRING(VoucharNo,LEN(#startFrom)+1,LEN(VoucharNo)- LEN(#Prefix)) AS INT))+1 AS varchar(100)) FROM dbo.Journal_Entry;
SET #sCode=CAST(#maxCode AS INT)
SELECT #Prefix + CAST(LEN(CAST(#maxCode AS VARCHAR(10))+1) AS VARCHAR(100)) + CAST(#maxCode AS VARCHAR(100))
END
ELSE
BEGIN
SELECT(#Prefix + CAST(#startFrom AS VARCHAR))
END
END
I got the same error message. In my case, it was due to not using quotes.
Although the column was supposed to have only numbers, it was a Varchar column, and one of the rows had a letter in it.
So I was doing this:
select * from mytable where myid = 1234
While I should be doing this:
select * from mytable where myid = '1234'
If the column had all numbers, the conversion would have worked, but not in this case.
Your problem seams to be located here:
SELECT #maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(#startFrom)+1,LEN(Voucher_No)- LEN(#Prefix)) AS INT)) AS varchar(100)) FROM dbo.Journal_Entry;
SET #sCode=CAST(#maxCode AS INT)
As the error says, you're casting a string that contains a letter 'J' to an INT which for obvious reasons is not possible.
Either fix SUBSTRING or don't store the letter 'J' in the database and only prepend it when reading.
The line
SELECT #Prefix + LEN(CAST(#maxCode AS VARCHAR(10))+1) + CAST(#maxCode AS VARCHAR(100))
is wrong.
#Prefix is 'J' and LEN(...anything...) is an int, hence the type mismatch.
It seems to me, you actually want to do,
SELECT
#maxCode = MAX(
CAST(SUBSTRING(
Voucher_No,
#startFrom + 1,
LEN(Voucher_No) - (#startFrom + 1)) AS INT)
FROM
dbo.Journal_Entry;
SELECT #Prefix + CAST(#maxCode AS VARCHAR(10));
but, I couldn't say. If you illustrated before and after data, it would help.
Try this one -
CREATE PROC [dbo].[getVoucherNo]
AS BEGIN
DECLARE
#Prefix VARCHAR(10) = 'J'
, #startFrom INT = 1
, #maxCode VARCHAR(100)
, #sCode INT
IF EXISTS(
SELECT 1
FROM dbo.Journal_Entry
) BEGIN
SELECT #maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(#startFrom)+1,ABS(LEN(Voucher_No)- LEN(#Prefix))) AS INT)) AS varchar(100))
FROM dbo.Journal_Entry;
SELECT #Prefix +
CAST(LEN(LEFT(#maxCode, 10) + 1) AS VARCHAR(10)) + -- !!! possible problem here
CAST(#maxCode AS VARCHAR(100))
END
ELSE BEGIN
SELECT (#Prefix + CAST(#startFrom AS VARCHAR))
END
END

SQL SERVER 2008 R2 string split

I want to split a column of strings say "99 crystal springs road" and get only 2 words (99 and crystal) respectively and update 99 to one column and crystal to another column of another table. How can I do it using charindex and substring?
Here is some sample code on how to do it ...
First, create this function:
CREATE FUNCTION [dbo].[GetStringPart]
(#fullString varchar(200), #pos tinyint)
RETURNS VARCHAR(200) -- return_data_type.
AS
BEGIN
IF #pos IS NULL OR #pos <= 0
SET #pos = 1
declare #secondPart varchar(200),#firstPart varchar(200),#output varchar(200)
declare #firstSpace int, #secondSpace int
set #firstSpace = CHARINDEX(' ', #fullString)
IF #firstSpace <= 0
RETURN ''
ELSE IF #pos = 1
BEGIN
SET #output = LTRIM(RTRIM(SUBSTRING(#fullString, 1, #firstSpace)))
END
ELSE
BEGIN
SET #secondSpace = CHARINDEX(' ', #fullString, CHARINDEX(' ', #fullString)+1) - CHARINDEX(' ', #fullString)+1
IF #secondSpace <= 0
SET #secondSpace = LEN(#fullString) - #firstSpace + 1
SET #output = LTRIM(RTRIM(SUBSTRING(#fullString, #firstSpace, #secondSpace)))
END
RETURN #Output
END
GO
Then you can use it like this:
declare #origTable table(name varchar(100))
insert into #origTable (name) values ('99 crystal springs road')
declare #newTable table(col1 varchar(100), col2 varchar(100))
INSERT INTO #newTable (col1, col2)
SELECT dbo.GetStringPart(name, 1), dbo.GetStringPart(name, 2) FROM #origTable
select * from #newTable
Assuming that you are selecting "99" and "crystal" just because they're the first two words...
You can do this in a single step but for ease of reading the solution I've separated it out
declare #sourceAddresses table
(
address varchar(100)
)
declare #split table
(
address varchar(100),
firstDelimiter int,
secondDelimiter int
)
declare #table table
(
part1 varchar(20),
part2 varchar(20)
)
insert into #sourceAddresses (address) values ('99 crystal springs road')
insert into #sourceAddresses (address) values ('100 elsewhere road')
insert into #split (address, firstDelimiter)
select address, charindex(' ', address)
from #sourceAddresses
update #split
set secondDelimiter = charindex(' ', address, (firstDelimiter+1))
where firstDelimiter > -1
insert into #table (part1, part2)
select substring(address, 0, firstDelimiter), substring(address, (firstDelimiter+1), (secondDelimiter-firstDelimiter))
from #split
where firstDelimiter > -1
and secondDelimiter > -1
select * from #table
Maybe something like this:
First create a function that gets part of the strings:
CREATE FUNCTION dbo.GetStringPart (#sep char(1), #s varchar(512),#pos int)
RETURNS VARCHAR(200)
AS
BEGIN
DECLARE #output VARCHAR(200)
;WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep, #s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(#sep, #s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT
#output=SUBSTRING(#s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END)
FROM Pieces
WHERE pn=#pos
RETURN #Output
END
GO
Then you can easy do this:
DECLARE #origalTable TABLE(name VARCHAR(100))
INSERT INTO #origalTable
VALUES('99 crystal springs road')
DECLARE #newTable TABLE(col1 VARCHAR(100), col2 VARCHAR(100))
INSERT INTO #newTable (col1, col2)
SELECT dbo.GetStringPart(' ',name, 1), dbo.GetStringPart(' ',name, 2) FROM #origalTable
SELECT * FROM #newTable
DROP FUNCTION dbo.GetStringPart

Resources