Linked server reference "Invalid Column Name" - sql

In SSMS 2012, I have created a linked server in SERVERA to SERVERB from which I have successfully written queries to multiple tables within the DBB database using a four part reference.
When I try to reference the 'Charge' table in the 'DBB' database with a simple select statement:
SELECT * FROM [SERVERB].[DBB].dbo.Charge
I get the following message:
Msg 207, Level 16, State 1, Line 1 Invalid column name 'charge_type'.
This column exists in the DBB database as 'Charge_Type', however, the collation of SERVERB is case insensitive, whereas the collation of SERVERA is case sensitive (which is where, I believe, my problem lies).
Does anyone have experience with this issue?

(For the people who might end up here)
You can change the collation on the fly. In this case, you have to write the name of the column names in the select query. What I mean is,
rather than writing query like this:
SELECT * FROM [SERVERB].[DBB].dbo.Charge
write the query like this:
SELECT Charge_Col1, Charge_Col2, Charge_Type COLLATE Latin1_General_CI_AS FROM [SERVERB].[DBB].dbo.Charge
There is another post similar to this: how we can select two columns having different collation

Related

Ignore Case Sensitivity While Querying Data

I have a database in Azure SQL Server with collation as 'SQL_Latin1_General_CP1_CS_AS' and in that i have table that has two columns
CREATE TABLE DBO.TABLE1(
[ROWID] [numeric](16, 0) IDENTITY(1,1) NOT NULL,
[CODE] [varchar](10) NOT NULL,
)
Now below query works fine in Azure SQL ignoring the case sensitivity of column names
SELECT rowID, coDE FROM DBO.TABLE1
SELECT rowid, code FROM DBO.TABLE1
But when i create the database on a Sql Server inside Azure VM (IaaS solution) with same collation setting: 'SQL_Latin1_General_CP1_CS_AS' then above queries are not working at all its throwing below error:
Msg 207, Level 16, State 1, Line 1
Invalid column name 'rowid'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'code'.
How do i suppress this case sensitivity of column name while querying tables in Sql server on Azure VM.
Please advice.
Azure SQL Database always uses contained database collation, which allows you to have a case-sensitive database without having a case-sensitive catalog (yuck).
In a contained database, the catalog collation
Latin1_General_100_CI_AS_WS_KS_SC. This collation is the same for all
contained databases on all instances of SQL Server and cannot be
changed.
In SQL Sever on an Azure VM you can get the same behavior by using a contained database. Your database collation (and the default collation of all your table columns) can be SQL_Latin1_General_CP1_CS_AS, but your table names, column names, proc names, etc will use the case-insensitive Latin1_General_100_CI_AS_WS_KS_SC.
SQL_Latin1_General_CP1_CS_AS is case-sensitive, compare to SQL_Latin1_General_CP1_CI_AS which is case-insensitive. It's better to change your DB collation.

How to store the result of select statement into the temporary table in Oracle?

We can write select column1,column2 into #temp from tableName in SQL Server. But I am unable to write the same query in an Oracle database.
I want to store the result of select/insert/delete/update or any result set into a local temporary table in oracle database. How I can do this?
I am executing below query in my Oracle sql developer tool:
select * into #temp
from bmi;
but I am getting the error as follow please help to find this error.
when I execute the same query in Microsoft SQL Server it get executed & #temp table get created which is not present in the database but it can hold the data for that particular session. so i want same scenario in ORACLE database.
ORA-00911: invalid character
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than
letters and numbers. $#_ are also allowed after the first
character. Identifiers enclosed by doublequotes may contain
any character other than a doublequote. Alternative quotes
(q'#...#') cannot use spaces, tabs, or carriage returns as
delimiters. For all other contexts, consult the SQL Language
Reference Manual.
*Action:
Error at Line: 1 Column: 15
I want to store the result of select/insert/delete/update or any result set into a local temporary table in oracle database,How I can Do This?
You can't. Oracle doesn't have local temporary tables, it doesn't work like that. But it doesn't need to. Oracle has a very different internal model from SQL Server which means a lot of SQL Server practices are unnecessary in Oracle. (To be fair SQL Server has neat things which Oracle doesn't, like ANSI 92 Joins for DML.)
The key insight is: you don't want to store the result of select/insert/delete/update or any result set into a local temporary table. That is something you had to do in T-SQL to achieve the end goal of implementing some business logic. But what you actually wanted to do in SQL Server and what you want to do in Oracle is write some code which delivers value to your organisation.
So, with that mindset in place, what do you need to do?
If you want to loop round a result set then perhaps a Cursor Loop is what you're looking for?
for rec in ( select * from some_table
where the_date = date '2018-02-01' )
loop
...
If you want to work on some data prior to inserting it into a data then perhaps you should use a PL/SQL collection:
type l_recs is table of some_table%rowtype;
But maybe you just need to understand Oracle's Transaction Management model. A lot of things are possible in pure SQL without any need for procedural framework.
Create temporary table :
create global temporary table
results_temp (column1, column2)
on commit preserve rows;
and then insert to it from your table:
insert into results_temp (column1, column2 )
SELECT column1,column2
FROM source_table
create global temporary table temp_table_name
on commit preserve rows as select column1,column2,columnN from your_table;

Using .. (two dots) when specifying the table being queried FROM

What is the purpose of the two dots in the following SQL statement?
select * from msdb..backupset
I understand that one would mean select from the table called 'backupset' with the 'msdb' database. But two dots is doing something different, which I do not understand.
The login would have default "schema" on the database that is connected to (in your case msdb). Specifying the object (in your case "backupset") with 3-part name like [DB name]..[Object Name] is omitting of the schema name (in your case probably "dbo") in the 3-part name.
There could be MyDatabase.SchemaA, and MyDatabase.SchemaB on a database MyDatabase database, and each schema could have 2 separate tables with same object name -- like MyDatabase.SchemaA.MyTable, and MyDatabase.SchemaB.MyTable.
If your login to MyDatabase defaults to SchemaA, and and run SELECT * FROM MyDatabase..MyTable, then you would be selecting from MyDatabase.SchemaA.MyTable.
If you wanted to select from the second table, you'd have to SELECT * FROM MyDatabase.SchemaB.MyTable or SELECT * FROM SchemaB.MyTable
Typically it is said that specifying the schema name explicitly is good practice (instead of backupset or MyTable, write dbo.backupset or SchemaA.MyTable
Using the two dots in this three-part naming convention (i.e Database.schema.table) indicates that the schema is the default schema(dbo)

Ambiguous Column Error In SQL Select Statement

SELECT IB,*
FROM SaleOrder
WHERE IB IS NOT NULL
ORDER BY IB
Error :
Msg 209, Level 16, State 1, Line 1
Ambiguous column name 'IB'.
Can somebody please explain why am I getting error while executing above SQL statement in SQL Server 2012 whereas same runs fine in SQL Server 2008?
My guess is your SQL Server 2008 database is in SQL Server 2000 compatibility mode, because normally it should return the same error as your 2012 instance.
Try fully qualifying the table name in your query and running it in SQL Server 2008 in the context of a database with the default compatibility level (e.g. in the context of tempdb), and you will likely see the error.
The difference in behaviour is by design and is documented in this Technet article as follows (emphasis added):
Compatibility-level setting of 80
…
When binding the column references in the ORDER BY list to the columns defined in the SELECT list, column ambiguities are ignored and column prefixes are sometimes ignored. This can cause the result set to return in an unexpected order.
Your table already contains column IBID so in ORDER BY clause sql server is not able to decide which column to access and sort by , IBID from table obtained in * or IBIS column specified at beginning in SELECT list
Select IBID,s.* from SaleHeader s WHERE IBID IS NOT NULL Order BY s.IBID
specify an alias to table as shown above
Select * from SaleHeader WHERE IBID IS NOT NULL Order BY IBID
That is because you are selecting IBID column twice.
Try:
Select * from SaleHeader WHERE IBID IS NOT NULL Order BY IBID
That is because the column IBID occurs twice in your results now.
You should either add an alias or remove the column.
So either this:
Select * from SaleHeader WHERE IBID IS NOT NULL Order BY IBID
Or:
Select s.IBID colX,* from SaleHeader s WHERE s.IBID IS NOT NULL Order BY s.IBID
About the 'why':
Is the query exact the same? Maybe the interpreter is different on both platforms. Is there a difference in your use of this query? (for example, do you run this separately or as a view definition. that differs a lot in how it is analyzed)
your table have already that column. if you use 2 times column in one query than sql server need to specify which table column want to access. use tablename.column name in order by.
SELECT IBID,*
FROM SaleHeader
WHERE IBID IS NOT NULL
ORDER BY SaleHeader.IBID

How can I convert "SQL_Latin1_ General" Collate Using an SSIS Package?

We've just noticed 2 of our servers have been set up using SQL_Latin1_General_CP1_CI_AS and Latin1_General_CI_AS.
I've created a script which compares two sources of data again each other (as it's a simple SELECT statement I haven't included it, it uses the same columns but from different sources) when I tried to union them together I received the collate error.
Msg 468, Level 16, State 9, Line 2
Cannot resolve the collation conflict between
"SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the UNION operation.
One of the sources is a table which is being populated by an SSIS package, is there a way of adapting the SSIS project to convert the "SQL_Latin1_General_CP1_CI_AS" format to "Latin1_General_CI_AS" before it's sent to the destination table?
Thanks!
You can use the sentence COLLATE Latin1_General_CI_AS after each column in the table that use SQL_Latin1_General_CP1_CI_AS like this.
SELECT COLUMN_A COLLATE Latin1_General_CI_AS AS COL1
FROM TABLE
Your error message looks like your UNION is in a single SQL statement?
e.g SELECT ... UNION ... SELECT
As Shiva described, within your SSIS Data Flow, you can use two (or more) OLE DB Source objects and combine them with a "Union All" transformation. Each OLE DB Source object will have just a single SELECT with no UNION clause. This design also has advantages in design/maintenance (unions on column names, no need to fill every column from every source) and runtime throughput.
I think you also need to use this technique on the OLE DB Source objects.
http://blog.stevienova.com/2009/04/16/ssis-pulling-data-from-a-non-default-collation-db-to-a-default-collation-db/