SQL take part of text to update another field - tsql

I have a field in my database called filename - it will always follow this format -
[BatchId][CompanyId][FinancialPeriod]
An example would be
001_100_201710
What I would like to do is from that string of text take the [BatchId] so whatever is before the first under score and update another field called Batch in the database. Not sure how to just get the Batch Id.
Thanks in advance

You can split using something like this
DECLARE #filename as varchar(100)
set #filename = '001_100_201710'
DECLARE #index INT
set #index = CHARINDEX('_', #filename)
select SUBSTRING(#filename, 0, #index ) BatchId

Related

Value not Store in Dynamic SQL

I've different different tables to categorically store data and a log table where all the transactions log are recorded
e.g. 1) VoucherNO, Add, ...
2) VoucherNO, Delete, ..
After I backup the database and restore in another server for my Reporting Purpose. That time I want to ensure all the log data and transaction are available in TestDB if not then I remove log from 'AUD_USER_ACTIVITY'.
To find the transaction exist or not, I create a dynamic sql select statement and check whether record is exist or not.
Basis on #RecExist Value I do the action like if records is not available in TestDB the log will be remove, if record exist immediately break this loop and going for next procedure
But #RecExist variable is not updating in Dynamic SQL Execution. Please guide me
declare #MvDocNo varchar(50)
DECLARE #SCtr as DECIMAL(10,0)
declare #LocationCode varchar(4)
declare #UName Nvarchar(40)
declare #toe varchar(30)
declare #QryTxt as nvarchar(MAX);
Declare #RecExist as INT =0;
SET #RecExist=0
WHILE #RecExist=0
BEGIN
select top 1 #MvDocNo=DOCNO, #SCtr=SrlNo,#LocationCode =DMLTYPE,#UName=TABLENAME
FROM R_AUDDB..AUD_USER_ACTIVITY
WHERE DBNAME='TestDB' and DMLTYPE not in ('AD','D','PD') ORDER BY SRLNO DESC;
select top 1 #toe=docno from TestDB..M_TYPEOFENTRY where TBLNAME=#UName;
set #QryTxt='Select #RecExist=1 From R_TestDB..'+#UName+ ' Where '+#toe+'='''+#MvDocNo+''''
exec (#QryTxt)
IF #RecExist=0
BEGIN
DELETE R_AUDDB..AUD_USER_ACTIVITY WHERE SRLNO=#SCtr
END
END
The following code sample demonstrates how to check for a row in a table with a specific column and value using dynamic SQL. You ought to be able to change the values of the first three variables to reference a table and column in your database for testing.
Note that SQL injection is still possible: there is no validation of the table or column names.
-- Define the table to check and the target column name and value.
declare #TableName as SysName = 'Things';
declare #ColumnName as SysName = 'ThingName';
declare #TestValue as NVarChar(32) = 'Beth';
-- Create a SQL statement to check for a row in the target table with the specified column name and value.
declare #SQL as NVarChar(1024);
declare #Result as Bit;
-- Note that only object names are substituted into the statement at this point and QuoteName() is used to reduce problems.
set #SQL = N'select #iResult = case when exists ( select 42 from dbo.' + QuoteName( #TableName ) +
N' where ' + QuoteName( #ColumnName ) + N' = #iTestValue ) then 1 else 0 end;'
select #SQL as SQL;
-- Execute the SQL statement.
-- Note that parameters are used for all values, i.e. the target value and return value.
execute sp_executesql #stmt = #SQL,
#params = N'#iTestValue NVarChar(32), #iResult Bit output',
#iTestValue = #TestValue, #iResult = #Result output
-- Display the result.
select #Result as Result;

How to partial match words within a string - TSQL

I have a table called Keywords that 100's of keywords ranging from one word to several, all separated by commas. For example:
change of name, asb, repair, reporting violence
These keywords are grouped into categories.
We have users who can enter any text into a free text field. Example:
Caller rang to to speak to ASB about violence
How do I use SQL to read the words in the free text field to check for any matches in the keyword table? So in the example above I want it to pick up that ASB and Violence was stored in the Keyword table.
I would also want it bring back a result if only one word was used like ASB.
It's important to note that any words could be entered into the free text field.
I'm using Microsoft SQL Server 2014 SP2.
Thanks
As you have not specified your table names; I will create some. Please run this:
create table dbWords (id int not null identity, words varchar(100), primary key (id))
insert into dbWords (words) values ('change of name, asb, repair, reporting violence')
CREATE FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output (splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
ENd
Then run this:
select * from dbWords inner join (
select * from dbo.fnSplitString('change of name, change of dob', ',')
) as splitdatatable on dbwords.words like '%,' + splitdata+ ',%'
or dbwords.words like '%,' + splitdata
or dbwords.words like splitdata + ',%'
The text passed to the function in the SQL statement above is the text entered by the user.

not sure how to populate a table based on the contents of another table

I've tried to figure my way around this but I'm relatively new to tsql.
These are my two tables:
This is my dbo.UsersAccountLink table:
This is my Company.Token tables:
Right now the UsersAccountLink.CorporationId is blank and I need to populate it based on what is in the Company.Token table.
So, I need to loop through each record in the Company.Token table and get the Company.Token.TokenId value and then query the Company.Token table with the TokenId, then lastly, I need to update the record on the dbo.UsersAccountLink table with the CorporationId.
Ultimately I want to update the dbo.UsersAccountLink.CorporationId with the value from Company.Token.CorporationId.
I hope that makes sense.
Well, here is what I have so far... It's not much but I'm struggling.
USE SuburbanPortal
go
-- Get the number of rows in the looping table
DECLARE #RowCount INT
SET #RowCount = (SELECT COUNT(*) FROM dbo.UsersAccountLink)
-- Declare an iterator
DECLARE #I INT
-- Initialize the iterator
SET #I = 1
-- Loop through the rows of a table #myTable
WHILE (#I <= #RowCount)
BEGIN
-- Declare variables to hold the data which we get after looping each record
DECLARE #CorpId UNIQUEIDENTIFIER, #TokenId UNIQUEIDENTIFIER
-- Get the data from table and set to variables
SET #TokenId = (SELECT [TokenId] FROM [SuburbanPortal].[dbo].[UsersAccountLink])
SET #CorpId = (SELECT [CorporationId] FROM [SuburbanPortal].[Company].[Token] WHERE #TokenId = ???)
-- Increment the iterator
SET #I = #I + 1
END
Welcome to SQL Server. Your code indicates that you are coming from a programming background with this pattern called "row-by-agonizing-row" (ROAR). The first order of business is to replace the "loop" thinking with "join". Instead of looping through a table then search for match in the other, use join:
UPDATE UAL
SET UAL.CorporationId = T.CorporationId
FROM dbo.UserAccountLink UAL
INNER JOIN Company.Token T ON UAL.TokenId = T.TokenId

comma separated value in sql statement from a variable

I am getting comma separated value like this in a variable (let say variable name #listobj)
'abc' , 'xyz'
but when I am using below statement it is not giving me the correct result
SELECT * FROM someTable
Where column1 IN (#listobj)
but abc is present in the table.
Where I am doing it wrong?
create a function that split the string to
CREATE FUNCTION dbo.Split(#String varchar(8000), #Delimiter char(1))
returns #temptable TABLE (items varchar(8000))
as
begin
declare #idx int
declare #slice varchar(8000)
select #idx = 1
if len(#String)<1 or #String is null return
while #idx!= 0
begin
set #idx = charindex(#Delimiter,#String)
if #idx!=0
set #slice = left(#String,#idx - 1)
else
set #slice = #String
if(len(#slice)>0)
insert into #temptable(Items) values(#slice)
set #String = right(#String,len(#String) - #idx)
if len(#String) = 0 break
end
return
end
then make call to the function SELECT * FROM someTable
Where column1 IN (dbo.Split(#listobj))
enter link description here
SQLFiddle demo
select * from someTable
where ','+LTRIM(RTRIM(#listobj))+',' LIKE '%,'+LTRIM(RTRIM(column1))+',%'
A classic question and the answer is no, you cannot use a parameter in this way. There are several workarounds though
One of which is to parse the value inside the stored procedure and dynamically generate sql inside the procedure to be execute later. However, this is not a good practice.
Refer to this question
How to pass a comma separated list to a stored procedure?
and also some good discussion on it here
http://social.msdn.microsoft.com/Forums/en-US/sqlintegrationservices/thread/1ccdd39e-8d58-45b2-9c21-5c4dbd857f95/

Conversion failed when converting the nvarchar value 'Internet Explorer 3 original' to data type int

In SQL Server 2008 (TSQL), I've created a stored procedure like this:
CREATE PROCEDURE SP_1_10_2
AS
declare #mostValuableBook nvarchar(255)
SELECT #mostValuableBook = Name
FROM books
WHERE price =
( SELECT MAX(price)
FROM books
WHERE izd LIKE '%BHV%' );
return #mostValuableBook
GO
But, when I'm trying to execute it:
declare #x nvarchar(255)
EXECUTE #x = SP_1_10_2;
SELECT 'The most expensive BHV book:', #x AS 'Name'
GO
I'm getting an error:
Conversion failed when converting the nvarchar value 'Internet
Explorer 3 original' to data type int.
It seems like the problem is in the line
EXECUTE #x = SP_1_10_2;
Can you please tell me what's wrong? Why is it trying to convert to int?
RETURN cannot be used to return nvarchar / varchar such as you have. RETURN is used to return an integer, this can be expressed as some sort of status code 1=True / 0=False. Read more about return here: http://msdn.microsoft.com/en-us/library/ms174998.aspx
In your case, you simply need to use OUTPUT variables which is similiar to pass-by-ref in C# or C++. You pass the variable to the sproc, the sproc modifies it, and you get the expected results after a SELECT....
Change it so that your parameters becomes an output parameter:
CREATE PROCEDURE SP_1_10_2
#mostValueableBook nvarchar(255) output
AS
SELECT #mostValuableBook = Name
FROM books
WHERE price =
( SELECT MAX(price)
FROM books
WHERE izd LIKE '%BHV%' );
SELECT #mostValuableBook
GO
Call it like so:
DECLARE #theValBook nvarchar(255)
EXECUTE SP_1_10_2 #mostValuableBook = #theValBook output
Then you can say:
SELECT 'Most expensive book is', #theValBook
You can also create a function to return the value you desire instead of relying on numeric return codes. SQL Functions come in quite handy. See example below which returns the last name with the highest client id using the LIKE operator
Use MYDB
GO
CREATE Function fn_LastClientIdByName
(
#nameLike NVARCHAR(10)
)
RETURNS NVARCHAR(100)
AS
BEGIN
DECLARE #result nvarchar(100)
DECLARE #clientName NVARCHAR(100)
SELECT top 1 #clientName = [clientLast] + ' ' + [clientFirst]
FROM [dbo].[duiClientOnly]
WHERE clientLast like #nameLike + '%'
order by clid desc
select #result = #clientName
return #result
END