SQL import from openrowset mixed type [keep leading 0, long ints and TEXT] correctly - sql

I have a column in Excel I'm trying to import, and it includes codes like the following:
01166
1166
2354654765432
xx132
I use IMEX=1 and everything imports as TEXT but when I assign the select to temporary table with nvarchar type, the codes with long numbers become incorrect:
1001051 becomes 1.00105e+006
I tried to cast to bigint, but this makes the code lose the leading 0 in 01166
this is my current query:
INSERT INTO #XTEMP
SELECT DISTINCT
(CASE ISNUMERIC([item_code]) WHEN 1 THEN CAST(CAST([item_code] AS BIGINT) AS nvarchar) ELSE CAST([item_code] AS nvarchar) END)
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0 Xml;HDR=YES;IMEX=1;Database=C:\path\file.xls',
'SELECT * FROM [sheet$]')

IMEX=1 allows reading mixed columns; it does not force data values to be text.
Looking at this SO page, you can see a possible workaround if you set HDR=NO, but that has its own complications.
If you can, the best thing to do is set the format of the column in the spreadsheet to Text.

Not exactly a fix, but more like a work around; I wrote an Excel Macro that appended a character (e.g. 'B') to the codes, then removed it when importing using Openrowset like:
select RIGHT([code], LEN([code])-1)

Related

How to determine properly data types when I have number in quotes or mixed data?

I know that this is very simple questions but I can't go any further. I want to import data from csv file to PostgreSQL. I have made a table, name column as they are named on the file and first problem that I have got is that I don't know the data type. I mean in first column when i open CSV file i have something like that:
"COLUMN1";"COLUMN2";"COLUMN3";"COLUMN4"
"009910";NA;NA;"FALSE"
"953308";0;41;"TRUE"
"936540";NA;NA;"FALSE"
"902346";1;5;"TRUE"
"747665";NA;NA;"FALSE"
"074554";NA;NA;"FALSE"
"154572";NA;NA;"FALSE"
And when I am import this base via pgAdmin 4 its return error with datatype. I set column2 as Integer but it's kinda 'mixed'. The column 1 I also set as integer but numbers are in quote so I wonder if PostgreSQL see it as string. The same is up to column4. How should I properly determine data types of each column?
During import it will cast the value to the column's type, if possible.
For example, if you do SELECT 'FALSE'::boolean it will cast and return false. SELECT '074554'::int works as well and returns 74554.
But the bare characters NA will give you problems. If those are intended to be null, try to do a find/replace on the file and just take them out, so that the first row of data has "009910";;;"FALSE" and see if that works.
You could also have all columns as text, quote the NA values, and import.
Then create a new table, and use INSERT INTO ... SELECT from the all-text table and manually cast or use CASE as needed to convert types.
For example, if you imported into a table called raw_data, and have a nicer table imports:
INSERT INTO imports
SELECT
column1::int,
CASE WHEN column2 = 'NA' THEN null ELSE column2::int END,
CASE WHEN column3 = 'NA' THEN null ELSE column3::int END,
column4::boolean
FROM
raw_data

Convert scientific notation back to numbers in SQL Server

I had data in Excel like
7540006
7540447
But when I import the data into SQL Server, it is saved as
7.54001e+006
7.54045e+006
So now when I try to convert it to back to original state, it's not ending up with the correct value.
I have tried following queries for conversion
declare #a varchar(40)
set #a = '7.54001e+006'
declare #b decimal(27, 12)
SELECT #b = CONVERT(REAL, #a, 2)
SELECT LTRIM(RTRIM(str(#a))), LTRIM(STR(#a))
SELECT CAST('7.54001e+006' as REAL)
and the output I am getting is addition of 3 to original value for all methods
i.e.
7540010
7540050
How do I convert it back to original state ??
Try the following query which gives the exact value
select CAST(CAST('7.54001e+006' AS FLOAT) AS bigint)
All data is stored as Unicode string 255 (DT_WSTR) in excel.
Read excel data as Unicode form. then do conversion in ssis or database using.
SELECT CAST('7.54001e+006' as REAL)
In excel data source >> connection manager >>Data access mode
== QUERY
SELECT * FROM [SheetName$]
when you will save in database that time convert value into toString() like
Convert.toString(7540006)
then it will save original value in database.

SQL Server comma delimiter for money datatype

I import Excel files via SSIS to SQL-Server. I have a temp table to get everything in nvarchar. For four columns I then cast the string to money type and put in my target table.
In my temp table one of those four columns let me call it X has a comma as the delimiter the rest has a dot. Don't ask me why, I have everything in my SSIS set the same.
In my Excel the delimiter is a comma as well.
So now in my target table I have everything in comma values but the X column now moves the comma two places to the right and looks like this:
537013,00 instead of 5370,13 which was the original cell value in the temp and excel column.
I was thinking this is a culture setup problem but then again it should or shouldn't work on all of these columns.
a) Why do I receive dot values in my temp table when my Excel displays comma?
b) how can I fix this? Can I replace the "," in the temp table with a dot?
UPDATE
I think I found the reason but not the solution:
In this X column in excel the first three cells are empty - the other three columns all start with 0. If I fill these three cells of X with 0s then I also get the dot in my temp table and the right value in my target table. But of course I have to use the Excel file as is.
Any ideas on that?
Try the code below. It checks whether the string value being converted to money is of numeric data type. If the string value is of numeric data type, then convert it to money data type, otherwise, return a NULL value. And it also replaces the decimal symbol and the digit grouping symbol of the string value to match the expected decimal symbol and digit grouping symbol of SQL Server.
DECLARE #MoneyString VARCHAR(20)
SET #MoneyString = '$ 1.000,00'
SET #MoneyString = REPLACE(REPLACE(#MoneyString, '.', ''), ',', '.')
SELECT CAST(CASE WHEN ISNUMERIC(#MoneyString) = 1
THEN #MoneyString
ELSE NULL END AS MONEY)
As for the reason why you get comma instead dot I have no clue. My first guess would be cultural settings but you already checked that. What about googling, did you get some results?
First the "separator" in SQL is the decimal point: its only excel that is using the comma. You can change the formatting in excel: you should format the excel column as money and specify a decimal point as the separator. Then in the SSIS import wizard split out the transformation of the column so it imports to a money data type. Its a culture thing, but delimiter tends to be used in the context of signifying the end of one column and the start of the next (as in csv)
HTH
Well thats a longstanding problem with excel. It uses the first 30 or so rows to infer data type. It can lead to endless issues. I think your solution has to be to process everything as a string in the way Yaroslav suggested, or supply an excel template to have data predefined and formatted data type columns, which then have the values inserted. Its a pita.

How to read values from Excel using Openrowset Function?

I am reading excel sheet using openrowset function?
My Excel sheet has numeric value in General Type Column. For some reason these values are brought over as nulls even though they have a values. I am not sure why this is happening. I looked into the format of the fields and they are set to General in Excel, I tried setting them to Text and that did not help.
I tried to bring the contents from the excel source to a text file in csv format and for some reason the Text field containing numeric value came out as blank (NULL).
Any inputs on getting this addressed will be much appreciated.
SET #Cmd = 'INSERT INTO Table_01
SELECT * FROM OPENROWSET(''Microsoft.Jet.OLEDB.4.0'', ''Excel 8.0;Database=' + #ExcelFilePath + ''',
''SELECT * FROM [Sheet1$]'')'
EXEC(#Cmd)
This is to do with TypeGuessRows and IMEX:
OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;HDR=YES;IMEX=1;Database=x.xls',
'SELECT * FROM [Sheet2$]');
TypeGuesssRows can be found at:
HKEY_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/
A value of 0 means all rows.

Converting a String to HEX in SQL

I'm looking for a way to transform a genuine string into it's hexadecimal value in SQL. I'm looking something that is Informix-friendly but I would obviously prefer something database-neutral
Here is the select I am using now:
SELECT SomeStringColumn from SomeTable
Here is the select I would like to use:
SELECT hex( SomeStringColumn ) from SomeTable
Unfortunately nothing is that simple... Informix gives me that message:
Character to numeric conversion error
Any idea?
Can you use Cast and the fn_varbintohexstr?
SELECT master.dbo.fn_varbintohexstr(CAST(SomeStringColumn AS varbinary))
FROM SomeTable
I'm not sure if you have that function in your database system, it is in MS-SQL.
I just tried it in my SQL server MMC on one of my tables:
SELECT master.dbo.fn_varbintohexstr(CAST(Addr1 AS VARBINARY)) AS Expr1
FROM Customer
This worked as expected. possibly what I know as master.dbo.fn_varbintohexstr on MS-SQL, might be similar to informix hex() function, so possibly try:
SELECT hex(CAST(Addr1 AS VARBINARY)) AS Expr1
FROM Customer
The following works in Sql 2005.
select convert(varbinary, SomeStringColumn) from SomeTable
Try this:
select convert(varbinary, '0xa3c0', 1)
The hex number needs to have an even number of digits. To get around that, try:
select convert(varbinary, '0x' + RIGHT('00000000' + REPLACE('0xa3c','0x',''), 8), 1)
If it is possible for you to do this in the database client in code it might be easier.
Otherwise the error probably means that the built in hex function can't work with your values as you expect. I would double check the input value is trimmed and in the format first, it might be that simple. Then I would consult the database documentation that describes the hex function and see what its expected input would be and compare that to some of your values and find out what the difference is and how to change your values to match that of the expected input.
A simple google search for "informix hex function" brought up the first result page with the sentence: "Must be a literal integer or some other expression that returns an integer". If your data type is a string, first convert the string to an integer. It looks like at first glance you do something with the cast function (I am not sure about this).
select hex(cast SomeStringColumn as int)) from SomeTable
what about:
declare #hexstring varchar(max);
set #hexstring = 'E0F0C0';
select cast('' as xml).value('xs:hexBinary( substring(sql:variable("#hexstring"), sql:column("t.pos")) )', 'varbinary(max)')
from (select case substring(#hexstring, 1, 2) when '0x' then 3 else 0 end) as t(pos)
I saw this here:
http://blogs.msdn.com/b/sqltips/archive/2008/07/02/converting-from-hex-string-to-varbinary-and-vice-versa.aspx
Sorrry, that work only on >MS SQL 2005
OLD Post but in my case I also had to remove the 0x part of the hex so I used the below code. (I'm using MS SQL)
convert(varchar, convert(Varbinary(MAX), YOURSTRING),2)
SUBSTRING(CONVERT(varbinary,Addr1 ) ,1,1) as Expr1