CHAR(4) did not show FOUR CHAR in Table Join - sql

Okay the title cannot explain the situation correct enough.
Now this is it,
I have a table with columns
Table1
Columns0, CHAR(20), NOT NULL.
Columns1, CHAR(4), Allow Nulls.
Data : 'ARR '
Table2
Columns0, CHAR(20), NOT NULL.
Columns1, CHAR(4), NOT NULL.
Data : 'ARR '
Then I join two tables together.
SELECT (ISNULL(a.Columns1,'') + ISNULL(b.Columns1,'')) AS WhatEver
FROM Table1 a
left join Table2 b on a.Columns0 = b.Columns0
The result should appear as 'ARR ARR '
instead of this, it appear as 'ARRARR '
Why does this happen?
EDIT 2012/06/11:
After struggling, I ended up doing things like:
SELECT ISNULL(CONVERT(CHAR(4),a.Columns1),'') + ISNULL(b.Columns1,'')
Then only I get correct result 'ARR ARR '
But I am pretty sure my data type is CHAR(4) in the database.
Thank guys..
EDIT 2012/08/06:
Another solution that I found working is to change the TABLE 2 COLUMN 1 to (CHAR(4), NULL).
This can be done through
ALTER TABLE [table_name] MODIFY [column_name] [column_data_type] [null|not null]

Your example works fine on my server (SQL Server 2008 R2):
create table SOxx1
(
col1 char(4),
col2 char(20) not null
)
create table SOxx2
(
col1 char(4),
col2 char(20) not null
)
Go
insert into SOxx1 (col1, col2) VALUES ('ARR ', 'abc')
insert into SOxx2 (col1, col2) VALUES ('ARR ', 'abc')
go
SELECT (ISNULL(a.col1,'') + ISNULL(b.col1,'')) AS WhatEver
FROM SOxx1 a
left join SOxx2 b on a.Col2 = b.Col2
-- OUTPUT is 'ARR ARR '

Are you sure your columns are CHAR and not VARCHAR?
Nothing is stripping spaces after you get the result from SQL Server?
Can you try this:
declare #table1 table (id int, one char(4))
declare #table2 table (id int, one char(4))
insert into #table1 values (1 ,'ARR ')
insert into #table2 values (1 ,'ARR ')
select (isnull(a.one,'') + isnull(b.one,'')) AS WhatEver
from #table1 a left join #table2 b on a.id = b.id
I get, as expected,
ARR ARR

Have you tried different collations?
SELECT ISNULL(a.Columns1,'') collate Latin1_General_BIN + ISNULL(b.Columns1,'') collate Latin1_General_BIN AS WhatEver
FROM Table1 a
left join Table2 b on a.Columns0 = b.Columns0

SELECT (ISNULL(a.Columns1,'') +ISNULL(b.Columns1,'')) AS WhatEver FROM Table1 a left join Table2 b on a.Columns0 = b.Columns0

Related

How do I join on a column that contains a string that I'm trying to search through using a substring?

I'm trying to join a table onto another table. The gimmick here is that the column from the table contains a long string. Something like this:
PageNumber-190-ChapterTitle-HelloThere
PageNumber-19-ChapterTitle-NotToday
I have another table that has a list of page numbers and whether or not I want to keep those pages, for example:
Page Number
Keep Flag
190
Y
19
N
I want to be able to return a query that contains the long string but only if the page number exists somewhere in the string. The problem I have is that, when using a LIKE statement to join:
JOIN t2 ON t1.string LIKE '%' + t2.page_number + '%' WHERE keep_flag = 'Y'
It will still return both results for whatever reason. The column of "Keep Flag" in the results query will change to "Y" for page 19 even though it shouldn't be in the results.
I obviously don't think LIKE is the best way to JOIN given that '19' is LIKE '190'. What else can I do here?
if Page_number is a number you must cats it as varchar, so that the types fit.
You can read on thehome page ,ot about cast and convert see https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16
CREATE TABLE tab1
([str] varchar(38))
;
INSERT INTO tab1
([str])
VALUES
('PageNumber-190-ChapterTitle-HelloThere'),
('PageNumber-19-ChapterTitle-NotToday')
;
2 rows affected
CREATE TABLE tab2
([Page Number] int, [Keep Flag] varchar(1))
;
INSERT INTO tab2
([Page Number], [Keep Flag])
VALUES
(190, 'Y'),
(19, 'N')
;
2 rows affected
SELECT str
FROM tab1 JOIN tab2 ON tab1.str LIKE '%' + CAST(tab2.[Page Number]AS varchar) + '%' AND tab2.[Keep Flag] = 'Y'
str
PageNumber-190-ChapterTitle-HelloThere
fiddle
Please try the following solution.
It is doing JOIN on the exact match.
SQL
-- DDL and sample data population, start
DECLARE #tbl1 TABLE (ID INT IDENTITY PRIMARY KEY, tokens VARCHAR(100));
INSERT #tbl1 (tokens) VALUES
('PageNumber-190-ChapterTitle-HelloThere'),
('PageNumber-19-ChapterTitle-NotToday');
DECLARE #tbl2 TABLE (ID INT IDENTITY PRIMARY KEY, Page_Number INT, Keep_Flag CHAR(1));
INSERT #tbl2 (Page_Number, Keep_Flag) VALUES
(190, 'Y'),
(19 , 'N');
-- DDL and sample data population, end
SELECT *
FROM #tbl1 AS t1 INNER JOIN #tbl2 AS t2
ON PARSENAME(REPLACE(t1.tokens,'-','.'),3) = t2.Page_Number
WHERE t2.keep_flag = 'Y';
Output
ID
tokens
ID
Page_Number
Keep_Flag
1
PageNumber-190-ChapterTitle-HelloThere
1
190
Y

update each row (sql server) based on subquery

I want to update each row of table1->keyField based on table2 value
Table1
Id|keyField
1|test_500
2|test_501
3|test_501
500,501 are primary key of and my another table2
Table2
Id|value
500|A
501|B
502|C
I have tried something like
update table1 set keyField=(select value from table2 where id=substring(expression))
but my select return multiple statement so unable to run the query.
any help or direction please?
You can use the syntax like this
UPDATE table1 SET keyField = Table2.Value
FROM table1 INNER JOIN table2
ON table1.Id = substring(expression))
If I get it right, this might be what you need:
UPDATE T1 SET
keyField = T2.Value
FROM
Table1 AS T1
INNER JOIN Table2 AS T2 ON T2.id = SUBSTRING(T1.keyField, 6, 100)
Careful when comparing substring result with an numeric value, might get a conversion error.
Try this code (necessary notes are in comments below):
--generate some sample data (the same as you provided)
declare #table1 table (id int, keyField varchar(10))
insert into #table1 values (1,'test_500'),(2,'test_501'),(3,'test_502')
declare #table2 table (id int, value char(1))
insert into #table2 values (500,'A'),(501,'B'),(502,'C')
--in case you want to see tables first
--select * from #table1
--select * from #table2
--here you extract the number in first table in keyField column and match it with ID from second table, upon that, you update first table
update #table1 set keyField = value from #table2 [t2]
where cast(right(keyfield, len(keyfield) - charindex('_',keyfield)) as int) = [t2].id
select * from #table1

Add values of a column of one table as columns to another table

I am getting trouble in inserting values of a column from one table as columns in another table.
I am having Table A with some values in col1 :
And another Table B with columns equal to values of col1.
I want to add rest of the values from Table A, col1 as columns in Table B. Please help me out solving my problem. I am using SQL server 2012.
Create table tableA
(
Col1 varchar(50)
)
Create table tableB
(
Col1 varchar(50)
)
Insert into tableA values ('abc')
Insert into tableA values ('bbb')
Insert into tableA values ('ddd')
Insert into tableA values ('Col2')
Insert into tableA values ('Col3')
go
Declare #colName varchar(5000), #Text varchar(5000)
if EXISTS (select 1 from sys.tables where object_id=OBJECT_ID('tableB'))
BEGIN
SELECT #colName=ISNULL(#colName,'')+ (Col1) + ' varchar(50), ' FROM tableA WHERE Col1 not in (SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('tableB'))
select #colName= SUBSTRING (#colName,0,LEN(#colName))
select #colName
SET #Text='ALTER table tableB Add '+#colName
END
ELSE
BEGIN
print 1
SELECT #colName=ISNULL(#colName,'')+ (Col1) + ' varchar(50), ' FROM tableA
group by Col1
select #colName= SUBSTRING (#colName,0,LEN(#colName))
select #colName
SET #Text = 'CREATE TABLE tableB ( '+#colName+' )'
END
select #Text
EXEC (#Text)
select * from tableA
select * from tableB

Use default value of a column in stored procedures

I am using SQL Server 2012 and I have 2 tables with the following definition
CREATE TABLE t1 (id INT PRIMARY KEY, value NVARCHAR(10))
CREATE TABLE t2 (id INT PRIMARY KEY, value BIT DEFAULT 1)
ALTER TABLE t2 WITH CHECK ADD CONSTRAINT FK FOREIGN KEY(id) REFERENCES t1 (id)
I inserted the following columns for the current example:
INSERT INTO t1 VALUES (1, 'a')
INSERT INTO t1 VALUES (2, 'b')
INSERT INTO t1 VALUES (3, 'c')
INSERT INTO t2 VALUES (1, 1)
INSERT INTO t2 VALUES (3, 0)
I am running this query and it works
SELECT
t1.*, ISNULL(t2.value, 1)
FROM
t1
LEFT JOIN t2 ON t1.id = t2.id
Is there any way to replace the 1 in this part ISNULL(t2.value, 1) with the default value that I have defined in the column value in the table t2?
Here is the sqlfiddle I created with this example: SQLFIDDLE DEMO
UPDATE 1:
I can't use SQL Server: Find out default value of a column with a query because it returns ((1)) and I can't cast ((1)) to BIT.
Is there any way to fix that?
You are not using the default in the manner it is intended. It is something SQL Server evaluates internally at time of insert (or potentially update if the default keyword is used).
It is not intended for use in SELECT. Consider that it can contain arbitrary expressions such as DEFAULT CAST(GETDATE() AS INT) % 2 or calling a Scalar UDF. Casting from string to bit won't evaluate those expressions for you.
The only way you could do something like this would be to evaluate it separately
DECLARE #B BIT
, #Definition NVARCHAR(max)
SELECT #Definition = N'SELECT #B = '
+ object_definition(default_object_id)
FROM sys.columns
WHERE NAME = 'value'
AND object_id = OBJECT_ID('dbo.t2')
EXEC sys.sp_executesql
#Definition,
N'#B BIT OUTPUT',
#B = #B OUTPUT
SELECT t1.*,
ISNULL(t2.value, #B)
FROM t1
LEFT JOIN t2
ON t1.id = t2.id
This works for me:
DECLARE #def as bit = null
SELECT #def
UNION ALL
SELECT ISNULL(#def, REPLACE(REPLACE((
SELECT COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'dual'
AND COLUMN_NAME = 'tempo'),'(', ''), ')', '')) As def

SQL Server SELECT into existing table

I am trying to select some fields from one table and insert them into an existing table from a stored procedure. Here is what I am trying:
SELECT col1, col2
INTO dbo.TableTwo
FROM dbo.TableOne
WHERE col3 LIKE #search_key
I think SELECT ... INTO ... is for temporary tables which is why I get an error that dbo.TableTwo already exists.
How can I insert multiple rows from dbo.TableOne into dbo.TableTwo?
SELECT ... INTO ... only works if the table specified in the INTO clause does not exist - otherwise, you have to use:
INSERT INTO dbo.TABLETWO
SELECT col1, col2
FROM dbo.TABLEONE
WHERE col3 LIKE #search_key
This assumes there's only two columns in dbo.TABLETWO - you need to specify the columns otherwise:
INSERT INTO dbo.TABLETWO
(col1, col2)
SELECT col1, col2
FROM dbo.TABLEONE
WHERE col3 LIKE #search_key
There are two different ways to implement inserting data from one table to another table.
For Existing Table - INSERT INTO SELECT
This method is used when the table is already created in the database earlier and the data is to be inserted into this table from another table. If columns listed in insert clause and select clause are same, they are not required to list them. It is good practice to always list them for readability and scalability purpose.
----Create testable
CREATE TABLE TestTable (FirstName VARCHAR(100), LastName VARCHAR(100))
----INSERT INTO TestTable using SELECT
INSERT INTO TestTable (FirstName, LastName)
SELECT FirstName, LastName
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable
For Non-Existing Table - SELECT INTO
This method is used when the table is not created earlier and needs to be created when data from one table is to be inserted into the newly created table from another table. The new table is created with the same data types as selected columns.
----Create a new table and insert into table using SELECT INSERT
SELECT FirstName, LastName
INTO TestTable
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable
Ref 1 2
It would work as given below :
insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""
If the destination table does exist but you don't want to specify column names:
DECLARE #COLUMN_LIST NVARCHAR(MAX);
DECLARE #SQL_INSERT NVARCHAR(MAX);
SET #COLUMN_LIST = (SELECT DISTINCT
SUBSTRING(
(
SELECT ', table1.' + SYSCOL1.name AS [text()]
FROM sys.columns SYSCOL1
WHERE SYSCOL1.object_id = SYSCOL2.object_id and SYSCOL1.is_identity <> 1
ORDER BY SYSCOL1.object_id
FOR XML PATH ('')
), 2, 1000)
FROM
sys.columns SYSCOL2
WHERE
SYSCOL2.object_id = object_id('dbo.TableOne') )
SET #SQL_INSERT = 'INSERT INTO dbo.TableTwo SELECT ' + #COLUMN_LIST + ' FROM dbo.TableOne table1 WHERE col3 LIKE ' + #search_key
EXEC sp_executesql #SQL_INSERT
select *
into existing table database..existingtable
from database..othertables....
If you have used select * into tablename from other tablenames already, next time, to append, you say select * into existing table tablename from other tablenames
IF you want a identity column in new table created with select into then it can be done as below.
SELECT
ID = IDENTITY(INT, 1, 1),
name
INTO table2
FROM table1
If you want to insert into Table_A, from Table_B, only if the column is not in Table_A, then use the following:
BEGIN TRANSACTION
INSERT INTO dbo.Table_A (Column_1)
SELECT DISTINCT Some_Column AS Column_1
FROM dbo.Table_B
WHERE Some_Column
NOT IN (SELECT DISTINCT GroupId
FROM dbo.Table_A)
COMMIT