How do I convert a nvarchar to a uniqueidentifer? - sql

I have a table (RPT.table1) that contains data that was exported from an ArcGIS Online application. One of the columns in the table (GlobalID) was exported as a nvarchar(255) datatype. I need to convert this column to a uniqueidentifier datatype before I insert this data into another table (CFAdmin.table2).
The values in the GlobalID column were once unique identifiers and already contain hyphens (B4A6AA96-42DF-48D9-A3E0-4C7F88ED3E1D).
I've tried using
ALTER TABLE RPT.table1
ALTER COLUMN GlobalID uniqueidentifier;
and in an INSERT INTO statement
INSERT INTO CFAdmin.table2 (GlobalID)
SELECT CAST(GlobalID AS uniqueidentifier)
FROM RPT.table1;
For both methods I get an error
Msg 8169, Level 16, State 2, Line 1
Conversion failed when converting from a character string to uniqueidentifier.
I'm relatively new to SQL Server and am guessing there is a pretty simple solution.
Thanks for reading.

Chances are there's an issue with your data, not with your code/syntax. There are probably values in the source table that are invalid as unique identifiers. I would investigate by just looking at the data in your source table and trying to find the values that would cause the error. See what this query returns:
Select GlobalID from RPT.table1 WHERE GlobalID NOT LIKE '________-____-____-____-____________'
(Those underscores blur together, so for the sake of being explicit: 8 underscores, dash, 4 underscores, dash, 4 underscores, dash, 4 underscores, dash, 12 underscores)
And maybe check
Select GlobalID from RPT.table1 WHERE GlobalID IS NULL

Related

Oracle insert value into a column with power

How can I insert a value into a column with power? Please see the below example:
Can it be done via the UNISTR function?
insert into table values ('2332239 12'); -- I intentionally want to insert the number into a varchar field.
If you mean you want to insert a string that ends with Unicode superscript 12 you can just put Unicode characters in a Unicode string and insert them into a Unicode column:
INSERT INTO table VALUES(N'123¹²')
(Your column will have to be an NVARCHAR)
If your column is a varchar and you can't change it you'll have to encode the data somehow, and decode it very time you want to use it (not ideal)

MS SQL does not allow VARCHAR over 128 characters, why?

I have a table with a column configured to hold nvarchar data type.
I am trying to add a row using
INSERT INTO TABLE_NAME VALUES (value1, value2...)
Sql-server gets stuck on a 180 character string that I am trying to assign to the nvarchar data type column returning:
Error: The identifier that starts with [part of string] is too long.
Maximum length is 128.
I don't understand why this is happening since nvarchar(max) should hold 2GByte of storage as I read here: What is the maximum characters for the NVARCHAR(MAX)?
Any ideas of what I've got wrong here?
UPDATE:
The table was created with this:
CREATE TABLE MED_DATA (
MED_DATA_ID INT
,ORDER_ID INT
,GUID NVARCHAR
,INPUT_TXT NVARCHAR
,STATUS_CDE CHAR
,CRTE_DTM DATETIME
,MOD_AT_DTM DATETIME
,CHG_IN_REC_IND CHAR
,PRIMARY KEY (MED_DATA_ID)
)
And my actual INSERT statement is as follows:
INSERT INTO MED_DATA
VALUES (
5
,12
,"8fd9924"
,"{'firstName':'Foo','lastName':'Bar','guid':'8fd9924','weightChanged':false,'gender':'Male','heightFeet':9,'heightInches':9,'weightPounds':999}"
,"PENDING"
,"2017-09-02 00:00:00.000"
,"2017-09-02 00:00:00.000"
,NULL
)
By default, double quotes in T-SQL do not delimit a string. They delimit an identifier. So you cannot use double quotes here. You could change the default but shouldn't.
If this is being directly written in a query window, use single quotes for strings and then double up quotes within the string to escape them:
INSERT INTO MED_DATA VALUES (5, 12, '8fd9924', '{''firstName'':''Foo'',''lastName'':''Bar'',''guid'':''8fd9924'',''weightChanged'':false,''gender'':''Male'',''heightFeet'':9,''heightInches'':9,''weightPounds'':999}', 'PENDING', '2017-09-02T00:00:00.000', '2017-09-02T00:00:00.000', NULL)
But if, instead, you're passing this string across from another program, it's time to learn how to use parameterized queries. That'll also allow you to pass the dates across as dates and not rely on string parsing to reconstruct them correctly.
Also, as noted, you need to fix your table definitions because they've currently nvarchar which means the same as nvarchar(1).
Are you aware of what an Identifier is? Here is a hint - it is a NAME. SQL Server is not complaining about your data, it is complaining about a field or table name. SOmehow your SQL must be totally borked so that part of the text is parsed as name of a field or table. And yes, those are limited to 128 characters.
This is clear in the error message:
Error: The identifier
clearly states it is an identifier issue.

Not Able to Insert Data into Database String or binary data would be truncated

INSERT INTO [CVSUAT].[dbo].[UserLevel ](
[Client_ID]
,[User_Level_Name]
,[User_Level_Description]
,[Created_by]
,[Created_Date]
,[Modified_by]
,[Modified_Date]
,[Delete_Flag]
,[Deactivate_Flag]) VALUES ('sndbsndbsdnbsndbsnbdnsbdn23','Client','','Client','2013-03-12 21:31:38.437','Client','2013-03-12 21:31:38.437','0','0')
Msg 8152, Level 16, State 4, Line 1
String or binary data would be truncated.
The statement has been terminated.
NOTE: My Table has a space [UserLevel ] as it was made that way from before
This is caused by attempting to put too much data into a column.
The trouble is, none of the values specified in your example are too large for the columns indicated in your schema picture. I'd therefore assume that the values you've given us either aren't the true values, or you've got a trigger on that table, which is actually what is causing the error.
As an aside, shouldn't your Delete_Flag and Deactivate_Flag columns be of datatype bit, rather than char(1)?
Edit:
Oh, and one more thing - as Client_ID is an nvarchar, you probably want to store unicode data in there. To indicate this in your script, you should use the "N" prefix on your strings, like so:
INSERT INTO [CVSUAT].[dbo].[UserLevel ](
[Client_ID]
,[User_Level_Name]
,[User_Level_Description]
,[Created_by]
,[Created_Date]
,[Modified_by]
,[Modified_Date]
,[Delete_Flag]
,[Deactivate_Flag]) VALUES (N'sndbsndbsdnbsndbsnbdnsbdn23','Client','','Client','2013-03-12 21:31:38.437','Client','2013-03-12 21:31:38.437','0','0')

SQL error "ORA-01722: invalid number"

A very easy one for someone,
The following insert is giving me the
ORA-01722: invalid number
why?
INSERT INTO CUSTOMER VALUES (1,'MALADY','Claire','27 Smith St Caulfield','0419 853 694');
INSERT INTO CUSTOMER VALUES (2,'GIBSON','Jake','27 Smith St Caulfield','0415 713 598');
INSERT INTO CUSTOMER VALUES (3,'LUU','Barry','5 Jones St Malvern','0413 591 341');
INSERT INTO CUSTOMER VALUES (4,'JONES','Michael','7 Smith St Caulfield','0419 853 694');
INSERT INTO CUSTOMER VALUES (5,'MALADY','Betty','27 Smith St Knox','0418 418 347');
An ORA-01722 error occurs when an attempt is made to convert a character string into a number, and the string cannot be converted into a number.
Without seeing your table definition, it looks like you're trying to convert the numeric sequence at the end of your values list to a number, and the spaces that delimit it are throwing this error. But based on the information you've given us, it could be happening on any field (other than the first one).
Suppose tel_number is defined as NUMBER - then the blank spaces in this provided value cannot be converted into a number:
create table telephone_number (tel_number number);
insert into telephone_number values ('0419 853 694');
The above gives you a
ORA-01722: invalid number
Here's one way to solve it. Remove non-numeric characters then cast it as a number.
cast(regexp_replace('0419 853 694', '[^0-9]+', '') as number)
Well it also can be :
SELECT t.col1, t.col2, ('test' + t.col3) as test_col3
FROM table t;
where for concatenation in oracle is used the operator || not +.
In this case you get : ORA-01722: invalid number ...
This is because:
You executed an SQL statement that tried to convert a string to a
number, but it was unsuccessful.
As explained in:
Oracle/PLSQL: ORA-01722 Error.
To resolve this error:
Only numeric fields or character fields that contain numeric values
can be used in arithmetic operations. Make sure that all expressions
evaluate to numbers.
As this error comes when you are trying to insert non-numeric value into a numeric column in db it seems that your last field might be numeric and you are trying to send it as a string in database. check your last value.
Oracle does automatic String2number conversion, for String column values! However, for the textual comparisons in SQL, the input must be delimited as a String explicitly: The opposite conversion number2String is not performed automatically, not on the SQL-query level.
I had this query:
select max(acc_num) from ACCOUNTS where acc_num between 1001000 and 1001999;
That one presented a problem: Error: ORA-01722: invalid number
I have just surrounded the "numerical" values, to make them 'Strings', just making them explicitly delimited:
select max(acc_num) from ACCOUNTS where acc_num between '1001000' and '1001999';
...and voilà: It returns the expected result.
edit:
And indeed: the col acc_num in my table is defined as String. Although not numerical, the invalid number was reported. And the explicit delimiting of the string-numbers resolved the problem.
On the other hand, Oracle can treat Strings as numbers. So the numerical operations/functions can be applied on the Strings, and these queries work:
select max(string_column) from TABLE;
select string_column from TABLE where string_column between '2' and 'z';
select string_column from TABLE where string_column > '1';
select string_column from TABLE where string_column <= 'b';
In my case the conversion error was in functional based index, that I had created for the table.
The data being inserted was OK. It took me a while to figure out that the actual error came from the buggy index.
Would be nice, if Oracle could have gave more precise error message in this case.
If you do an insert into...select * from...statement, it's easy to get the 'Invalid Number' error as well.
Let's say you have a table called FUND_ACCOUNT that has two columns:
AID_YEAR char(4)
OFFICE_ID char(5)
And let's say that you want to modify the OFFICE_ID to be numeric, but that there are existing rows in the table, and even worse, some of those rows have an OFFICE_ID value of ' ' (blank). In Oracle, you can't modify the datatype of a column if the table has data, and it requires a little trickery to convert a ' ' to a 0. So here's how to do it:
Create a duplicate table: CREATE TABLE FUND_ACCOUNT2 AS SELECT * FROM FUND_ACCOUNT;
Delete all the rows from the original table: DELETE FROM FUND_ACCOUNT;
Once there's no data in the original table, alter the data type of its OFFICE_ID column: ALTER TABLE FUND_ACCOUNT MODIFY (OFFICE_ID number);
But then here's the tricky part. Because some rows contain blank OFFICE_ID values, if you do a simple INSERT INTO FUND_ACCOUNT SELECT * FROM FUND_ACCOUNT2, you'll get the "ORA-01722 Invalid Number" error. In order to convert the ' ' (blank) OFFICE_IDs into 0's, your insert statement will have to look like this:
INSERT INTO FUND_ACCOUNT (AID_YEAR, OFFICE_ID) SELECT AID_YEAR, decode(OFFICE_ID,' ',0,OFFICE_ID) FROM FUND_ACCOUNT2;
I have found that the order of your SQL statement parameters is also important and the order they are instantiated in your code, this worked in my case when using "Oracle Data Provider for .NET, Managed Driver".
var sql = "INSERT INTO table (param1, param2) VALUES (:param1, :param2)";
...
cmd.Parameters.Add(new OracleParameter("param2", Convert.ToInt32("100")));
cmd.Parameters.Add(new OracleParameter("param1", "alpha")); // This should be instantiated above param1.
Param1 was alpha and param2 was numeric, hence the "ORA-01722: invalid number" error message. Although the names clearly shows which parameter it is in the instantiation, the order is important. Make sure you instantiate in the order the SQL is defined.
For me this error was a bit complicated issue.
I was passing a collection of numbers (type t_numbers is table of number index by pls_integer;) to a stored procedure. In the stored proc there was a bug where numbers in this collection were compared to a varchar column
select ... where ... (exists (select null from table (i_coll) ic where ic.column_value = varchar_column))
Oracle should see that ic.column_value is integer so shouldn't be compared directly to varchar but it didn't (or there is trust for conversion routines).
Further complication is that the stored proc has debugging output, but this error came up before sp was executed (no debug output at all).
Furthermore, collections [<empty>] and [0] didn't give the error, but for example [1] errored out.
The ORA-01722 error is pretty straightforward. According to Tom Kyte:
We've attempted to either explicity or implicity convert a character string to a number and it is failing.
However, where the problem is is often not apparent at first. This page helped me to troubleshoot, find, and fix my problem. Hint: look for places where you are explicitly or implicitly converting a string to a number. (I had NVL(number_field, 'string') in my code.)
This happened to me too, but the problem was actually different: file encoding.
The file was correct, but the file encoding was wrong. It was generated by the export utility of SQL Server and I saved it as Unicode.
The file itself looked good in the text editor, but when I opened the *.bad file that the SQL*loader generated with the rejected lines, I saw it had bad characters between every original character. Then I though about the encoding.
I opened the original file with Notepad++ and converted it to ANSI, and everything loaded properly.
In my case it was an end of line problem, I fixed it with dos2unix command.
In my case I was trying to Execute below query, which caused the above error ( Note : cus_id is a NUMBER type column)
select *
from customer a
where a.cus_id IN ('115,116')
As a solution to the caused error, below code fragment(regex) can be used which is added in side IN clause (This is not memory consuming as well)
select *
from customer a
where a.cus_id IN (select regexp_substr (
com_value,
'[^,]+',
1,
level
) value
from (SELECT '115,116' com_value
FROM dual)rws
connect by level <=
length ( com_value ) - length ( replace ( com_value, ',' ) ) + 1)
try this as well, when you have a invalid number error
In this
a.emplid is number and b.emplid is an varchar2 so if you got to convert one of the sides
where to_char(a.emplid)=b.emplid
You can always use TO_NUMBER() function in order to remove this error.This can be included as INSERT INTO employees phone_number values(TO_NUMBER('0419 853 694');

Entering special characters fails in Oracle table

I need to test if my application is reading special characters from the database and displaying them in exactly the same way. For this, I need to populate the database table with all special characters available. However, I am not sure how I can specify the special characters in the sql insert query. Can anyone please guide me to an example where I can insert a special character in the query? For simplicity sake, suppose the table is a City table with Area and Avg_Temperature being the 2 columns. If I need to insert the degree (celcius/farhenheit) symbol in Avg_Temperature column, how should I write the query?
*[Edit on 1/9/2012 at 2:50PM EST]*As per Justin Cave's suggestion below, I did following analysis:
Table: create table city(area number, avg_temperature nvarchar2(10));
Date: insert into city values (1100, '10◦C');
Query:
select dump(avg_temperature, 1010) from city where area = 1100;
O/P
DUMP(AVG_TEMPERATURE,1010)
----------------------------------------------------------
Typ=1 Len=8 CharacterSet=AL16UTF16: 0,49,0,48,0,191,0,67
Query
select value$ from sys.props$ where name='NLS_CHARACTERSET';
O/P
VALUE$
----------------
WE8MSWIN1252
Query:
select value$ from sys.props$ where name='NLS_NCHAR_CHARACTERSET';
O/P
----------------
AL16UTF16
It seems that the insert does mess up the special characters as Justin Cave suggested. But I am not able to understand why this is happening? Can anyone please provide related suggestion?
First you should not store the symbol as part of your column. That requires you to declare the column as VARCHAR which will give you lots of problems in the long run (e.g. you cannot sum() on them, you cannot avg() on them and so on)
You should store the unit in which the temperature was taken in a second column (e.g. 1 = celcius and 2 = fahrenheit) and translate this when displaying the data in the frontend. If you really want to store the symbol, declare the units columns as CHAR(1):
CREATE TABLE readings
(
area number(22),
avg_temperature number(10,3),
units varchar(2)
)
Then you can insert it as follows:
INSERT INTO readings
(area, avg_temperature, units)
VALUES
(1000, 12.3, '°C');
But again: I would not recommend to store the actual symbol. Store only the code!
First you need to know what the database character set is. Then you need to know what character set your "client" connection is using. Life is always easier if these are the same.
If your databse is utf-8 and your client is utf-8 then you don't need to do any character escaping you can just use the utf-8 encoding for the desired character.
In your example the degree character is unicode codepoint u+00b0.
In utf-8 this is a two-byte sequence: x'c2', x'b0'.