I have two views with identical columns. One of the columns on the first view is generated 'on the fly' and set as NULL and the same column on the other view has values stored as varchar. I have a stored proc that looks like this:
ALTER PROCEDURE [dbo].[mi_GetLearners]
(#centrename nvarchar(200))
AS
SELECT [centrename]
,[Name]
,[Username] --generated on the fly as NULL
FROM [DB1].[dbo].[vw_Learners]
WHERE [centrename] = #centrename
UNION
SELECT [centrename]
,[Name]
,[Username] --values stored as varchar
FROM [Linked_Server].[DB2].[dbo].[vw_Learners]
WHERE [centrename] = #centrename
DB1 is on SQL Server 2008 R2
DB2 is on SQL server 2005
When I run the stored proc I get the following error:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting
the varchar value 'someusername' to data type int.
Why is it trying to convert the value to int datatype as the other column is set as NULL? If I instead change the second column from NULL to ' ' the stored proc works fine... I'm really baffled as to why a union between a varchar column and NULL column generated in a select statement would throw such an error... any ideas?
EDIT: I'm looking for an explanation rather than a solution...
EDIT 2: Running the following code:
CREATE VIEW vw_myview
AS
SELECT NULL AS MyColumn
EXECUTE sp_help vw_myview
Returns:
Type Column_name
int MyColumn
The problem is that NULL is (to within some wiggle room) a member of every data type.
When any SELECT query is being run, the contents of each column must be of one type, and only one type. When there are a mixture of values in a column (including NULLs), the type can obviously be determined by examining the types of the non-NULL values, and appropriate conversions are performed, as necessary.
But, when all rows contain NULL for a particular column, and the NULL hasn't been cast to a particular type, then there's no type information to use. So, SQL Server, somewhat arbitrarily, decides that the type of this column is int.
create view V1
as
select 'abc' as Col1,null as Col2
go
create view V2
as
select 'abc' as Col1,CAST(null as varchar(100)) as Col2
V1 has columns of type varchar(3) and int.
V2 has columns of type varchar(3) and varchar(100).
I'd expect the type of the field to be determined by the first SELECT in the union. You may try changing the order of your two selects or change to CAST(NULL AS VARCHAR(...)).
I think you need to cast to the same datatype:
---
AS
SELECT [centrename]
,[Name]
,CAST(NULL AS VARCHAR(MAX)) AS [Username]
FROM [DB1].[dbo].[vw_Learners]
WHERE [centrename] = #centrename
UNION
---
Related
This question already has answers here:
T-SQL stored procedure that accepts multiple Id values
(5 answers)
Closed 2 years ago.
Having a table (Table1) with Columns -> Column1 int, Column2 int, Column3 varchar(128), Column4 char(11)
Need to create a stored procedure to get the details from Table1 based on the input parameter. Input parameter holds values with comma-separated. It has to be mapped with Column1
Create Procedure ProcedureName(#InputParams VARCHAR(MAX))
AS
BEGIN
SELECT Column2
,Column3
,Column4
FROM Table1
WHERE Column1 IN (#InputParams)
ORDER BY Column2
END
The below statement is throwing conversion error
"Conversion failed when converting the varchar value '123, 456, 789' to data type int."
EXEC ProcedureName #InputParams = '123, 456, 789'
Converting the SELECT statement to the dynamic query will work fine but will we able to fix the conversion issue in the static query. Please help me.
Well, you have a couple of options in this case :
Table-valued input parameter : For this, you'll have to create a UDT (user-defined table type) and use that as the parameter to your stored procedure.
Convert the comma-separated input string parameter into integers and then use them in the IN clause.
Not sure about your use-case, but generally, I would suggest going forward with the first option.
I am trying to change type of columns from varchar to integer. When I run the following command
alter table audio_session
alter column module_type_cd type INT USING module_type_cd::integer,
alter column sound_type_cd type INT USING sound_type_cd::integer
I got the error:
ERROR: invalid input syntax for integer: "string"
SQL state: 22P02
The error does not make any sense. There is no "string" in the command at all. What did I do wrong?
The columns audio_session.module_type_cd or audio_session.sound_type_cd has at least one non-numeric value among all values of each row. So, it's impossible to convert to a completely numeric data type.
As an example :
create table Table1( col1 varchar(10), col2 varchar(10) );
insert into Table1 values('1','1');
insert into Table1 values('2','2');
insert into Table1 values('3','C3');
select CAST(coalesce(col1, '0') AS integer) as converted from Table1; -- this works
select CAST(coalesce(col2, '0') AS integer) as converted from Table1; -- but, this doesn't
SQL Fiddle Demo
There is no "string" in the command at all.
But must be in the data. The command you're going to use tries to cast all the columns values to integer. Check this:
select *
from audio_session
where module_type_cd = 'string' or sound_type_cd = 'string';
I got the error where my data type is varchar, then I want to insert value/input in textboxt = 'smh85670s'.
It appear to be error. As far as I know varchar can accept characters and numbers, but why does it keep throwing this error?
If I insert value '123456' the table can accept that value.
Please guide me. What data type should I use?
Assuming that you are using Stored procedures (which have an insert query) or directly firing an insert query into DB, you must be sending all data as parameters like say #param1, #param2,...
Your insert query will be like
INSERT INTO Sometable ( Amount, textbox,... )
SELECT #param1, #param2 ,...
Just add a cast in this query to make it work
INSERT INTO Sometable ( Amount, textbox,... )
SELECT #param1, CAST(#param2 as varchar),...
What is the expected behaviour due to SQL Standard when we perform UNION on two tables with different data types:
create table "tab1" ("c1" varchar(max));
create table "tab2" ("c3" integer);
insert into tab1 values(N'asd'), (N'qweqwe');
insert into tab2 values(123), (345);
select
c_newname as myname
from
(
select "c1" as c_newname from "tab1"
union all
select "c3" from "tab2"
) as T_UNI;
MS SQL Server gives
Conversion failed when converting the varchar value 'asd' to data type
int.
but what is defined in the standard?
From T-SQL UNION page:
The following are basic rules for combining the result sets of two
queries by using UNION:
The number and the order of the columns must be the same in all queries.
The data types must be compatible.
When one datatype is VARCHAR and other is INTEGER then SQL Server will implicitly attempt to convert VARCHAR to INTEGER (the rules are described in the precedence table). If conversion fails for any row, the query fails. So this works:
INSERT INTO #tab1 VALUES(N'123'), (N'345');
INSERT INTO #tab2 VALUES(123), (345);
SELECT C1 FROM #tab1 UNION ALL SELECT C2 FROM #tab2
But this does not:
INSERT INTO #tab1 VALUES(N'ABC'), (N'345');
INSERT INTO #tab2 VALUES(123), (345);
SELECT C1 FROM #tab1 UNION ALL SELECT C2 FROM #tab2
-- Conversion failed when converting the varchar value 'ABC' to data type int.
The rules for conversion are described here:
T-SQL Data Type Precedence
Having said that, you can explicitly convert your integer data to varchar in order to make the query work (the datatype of result would be varchar).
If you want to use union all columns in every query need to have the same type.C3 must be converteted to varchar because c1 is varchar. Try below solution
create table "tab1" ("c1" varchar(max));
create table "tab2" ("c3" integer);
insert into tab1 values(N'asd'), (N'qweqwe');
insert into tab2 values(123), (345);
select
c_newname as myname
from
(
select "c1" as c_newname from "tab1"
union all
select cast("c3" as varchar(max)) from "tab2"
) as T_UNI;
I replaced "tab3" with "tab1" - I think it's typo.
The basic rule is-->
Either the datatype used should be same in two table(or)you should use cast or convert function to match the datatypes in those two tables.
SQL Standard:
1)The number and the order of the columns must be the same in all queries.
2)Column datatypes must be compatible: They need not be the same exact same type, but they must be of a type that SQL Server can implicitly convert.
I want to get just schema of arbitrary sql query in SQL server.
For example-
Create Table Tabl1(Ta1bID int ,col1 varchar(10))
Create Table Tabl2(Tab1ID int ,col2 varchar(20))
SQL Query -
SELECT col1, col2
FROM Tab1
INNER JOIN Tab2 ON Tab1ID = Tab2ID
Here result will have this schema-
Col1 varchar(10), Col2 varchar(20)
I want to know what will be schema of result.
PS : I have just read access on the server where I am executing this query.
Any way to do this?
The schema, you mean to say datatype right? For resulted datatype will you always know when you operate on table(s). In your case both column is varchar datatype, so it will give character datatype, that you may convert into any character datatype like varchar, nvarchar, char, ntext etc.
Basic thing is, table designing was/is done by, so that time we know why we define datatype, now when you execute query below , you always know what will come with datatype of each column.
SELECT col1, col2
FROM Tab1
INNER JOIN Tab2 ON Tab1ID = Tab2ID
This though will issue when you use dynamic query, where you run time add column as per your requirement and you then execute which may or may not give error, due to mismatch of wrong datatype.
like
declare #sqlstring nvarchar(max)
set #sqlstring = 'declare #t table (name varchar(50))
insert into #t values(''Minh''),(''Tinh''),(''Justin'')
Select * from #t where Name like ''%in%'''
EXEC sp_executesql #sqlstring
I had similar problem before, but I had to create tables (70+) of each query one by one.
If there is a pattern, write a tool to generate create table
statement.
If not and it's one time job, just create them manually.
If it's not one time job, you might be thinking, why would store temp
date in table instead of temp table.