How do I alter a column's datatype in SQL, but just for all rows after the column header? - sql

I have a column of varchar(10) called TITLE. Except for the first row, which contains the column header, the rest of the column happens to be all integers so I wanted to change the datatype to int.
ALTER TABLE X
ALTER COLUMN TITLE int
I get an error when converting the first row, which is the column header: "Conversion failed when converting the varchar value 'TITLE' to data type int.
So, how do I convert the data type for all rows, except the column header?

The short answer is No, you cannot mix data types in a single SQL column. Data types need to be consistent for things like sorting, building indexes, etc.
You could possibly use another table to store various column headers, or another column in the same table.
Using a NoSQL solution such as MongoDB might be an approach, depending on the type of data you're storing. These solutions allow you to be a lot more flexible with the schema, which can even differ per document.

Nope sorry you cannot have multiple data types on the same column.
Data types

You don't. A column isn't a collection of independent variables that can each have their own type. Everything in a column has the same type. If you're trying to do this, then your schema isn't likely what it should be. If you post a little more detail, you can likely get some answers with an improved schema.

You can't mix'n'match data types within a column. You can use fuzzy data types like VarBinary or XML and interpret them as you please.
OTOH, you can use sp_addextendedproperty to store column titles and other extraneous bits of fluff.

Related

Store both Image and Text in single column in SQL Server

I'm suppose to create reference table, to store key value pair.
Id
Key
Value
Thing is, i need to store both text and image as values, which kind of datatype should be better for this. most case ppl refer Varbinary. but i need to know which one was the best.
Thank You!
What if just store them as separate fields columns?
Id bigint, Key varchar(50), ValueBlob varbinary(max),ValueString varchar(max)
You have to use varbinary(max) unless you encode the image to, say, base 64
Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format
If you can't/won't, you'll need to CONVERT the text data into varbinary(max)
That answers your actual question, but does not solve your problem
How will you know what type is stored in the column?
You'll need an extra column to store "type"
Do you intend to search/export the text stored in varbinary in the database?A lot of extra work
A key-value table structure suggests an EAV design which brings a lot of other problems.
Correct solutions:
separate tables for each type of data
separate varchar and varbinary columns

SQLServer - Exclude NTEXT columns while comparing data using EXCEPT/INTERSECT

In my SQL, I would need to compare data between two tables in SQLServer 2008R2 to return the rows where mismatch is present (using EXCEPT) and likewise matching rows in other cases (INTERSECT). The problem is, some of the columns have NTEXT datatype (SQLServer), and SQLServer gives error when such tables having columns with NTEXT are present.
Example:
SELECT * FROM table_pre
EXCEPT
SELECT * FROM table_post
The above operation gives an error -
'The ntext data type cannot be selected as DISTINCT because it is not comparable.'
I believe that tables (table_pre, table_post) have at least one column of datatype = NTEXT that is causing the comparison to fail.
Question -
1. Is there some way to exclude these NTEXT columns from the above comparison, without me having to explicitly list out the column names and excluding the problem column? There's a large number of columns involved and explicitly listing is not easy.
2. Can I just explicitly cast/convert the NTEXT column alone to say VARCHAR, and still go by not having to list down the rest of the columns?
3. Or, in general, can I somehow exclude certain columns by listing those out during such comparisons?
Any suggestions, really appreciated! Thanks.
Question - 1. Is there some way to exclude these NTEXT columns from the above comparison,
Yes, use explicitly the column names.
without me having to explicitly list out the column names and excluding the problem column?
Using * is a bad habit, you well deserve the error for abusing it.
There's a large number of columns involved and explicitly listing is not easy
Is actually trivial, build the statement dinamycally
Can I just explicitly cast/convert the NTEXT column alone to say VARCHAR
No. You have to convert to NVARCHAR, the N is very important. But, yes you can convert.
Or, in general, can I somehow exclude certain columns by listing those out during such comparisons
Fortunately no. SQL does not randomly decide what columns are or are not part of a result, so you get the predictability you desire.
So, in conclussion:
never use *
build complex statements dynamically. SELECT ... FROM sys.columns is your friend, you can easily build it in a few seconds
ditch the deprecated TEXT, NTEXT and IMAGE types

Changing column datatype from DECIMAL(9,0) to DECIMAL(15,0)

Can you please help me concerning this matter (I didnĀ“t found it in the Teradata documentation, which is honestly little overwhelming): My table had this column -BAN DECIMAL(9,0)-, and now I want to change it to - BAN DECIMAL(15,0) COMPRESS 0.- How can I do it? What does COMPRESS constraint 0. or any other mean anyway?
I hope this is possible, and I don`t have to create a new table and then copy the data form the old table. The table is very very big - when I do COUNT(*) form that table I get this error: 2616 numeric overflow occurred during computation
The syntax diagram for ALTER TABLE doesn't seem to support directly changing a column's data type. (Teradata SQL DDL Documentation). COMPRESS 0 compresses zeroes. Teradata supports a lot of different kinds of compression.
Numeric overflow here probably means you've exceeded the range of an integer. To make that part work, just try casting to a bigger data type. (You don't need to change the column's data type to do this.)
select cast(count(*) as bigint)
from table_name;
You asked three different questions:
You cannot change the data type of a column from DECIMAL(9,0) to DECIMAL(15,0). Your best bet would be to create a new column (NEW_BAN), assign values from your old column, drop the old column and rename NEW_BAN back to BAN).
COMPRESS 0 is not a constraint. It means that values of "zero" are compressed from the table, saving disk space.
Your COUNT(*) is returning that error becasue the table has more than 2,147,483,647 rows (the max value of an INTEGER). Cast the result as BIGINT (as shown by Catcall).
And I agree, the documentation can be overwhelming. But be patient and focus only on the SQL titles for your exact release. They really are well written.
You can not use ALTER TABLE to change the data type from DECIMAL(9,0) to DECIMAL(15,0) because it cross the byte boundary required to store the values in the table. For Teradata 13.10, see the Teradata manual for SQL Data Definition Language Detailed Topics pages 61-65 for more details on using ALTER TABLE to change column data types.

Does changing the datatype of a column after data is already there destroy the data?

Let's say I have a column of varchar(40) with data already and i change the datatype of that column to integer. does the data change at all in the columns (ie, does the data 'corrupt') or does it not matter and a table of (1,2,3) will still be (1,2,3) regardless of the datatype?
It will be the same, subject to
datatype conversion error (eg "foo" to int)
truncation (eg "foobar" in char(4))
If you attempt to change a column's datatype and the new type is incompatible with the old type, it will fail and nothing will change. You'll get an error like:
"Disallowed implicit conversion from data type <type> to data type <type2>".
Your first problem when you do something like this is that not all the data may meet the criteria to make the change. Those records need to be found and fixed before changing a data type.
The safest way to do something like this is to:
Make a backup
Find and fix any data that will not meet the criteria for the new datatype
Create an additional column in the correct datatype
Migrate the data
Drop the orginal column
Rename the new column to the old name

Force numerical order on a SQL Server 2005 varchar column, containing letters and numbers?

I have a column containing the strings 'Operator (1)' and so on until 'Operator (600)' so far.
I want to get them numerically ordered and I've come up with
select colname from table order by
cast(replace(replace(colname,'Operator (',''),')','') as int)
which is very very ugly.
Better suggestions?
It's that, InStr()/SubString(), changing Operator(1) to Operator(001), storing the n in Operator(n) separately, or creating a computed column that hides the ugly string manipulation. What you have seems fine.
If you really have to leave the data in the format you have - and adding a numeric sort order column is the better solution - then consider wrapping the text manipulation up in a user defined function.
select colname from table order by dbo.udfSortOperator(colname)
It's less ugly and gives you some abstraction. There's an additional overhead of the function call but on a table containing low thousands of rows in a not-too-heavily hit database server it's not a major concern. Make notes in the function to optomise later as required.
My answer would be to change the problem. I would add an operatorNumber field to the table if that is possible. Change the update/insert routines to extract the number and store it. That way the string conversion hit is only once per record.
The ordering logic would require the string conversion every time the query is run.
Well, first define the meaning of that column. Is operator a name so you can justify using chars? Or is it a number?
If the field is a name then you will use chars, and then you would want to determine the fixed length. Pad all operator names with zeros on the left. Define naming rules for operators (I.E. No leters. Or the codes you would use in a series like "A001")
An index will sort the physical data in the server. And a properly define text naming will sort them on a query. You would want both.
If the operator is a number, then you got the data type for that column wrong and needs to be changed.
Indexed computed column
If you find yourself ordering on or otherwise querying operator column often, consider creating a computed column for its numeric value and adding an index for it. This will give you a computed/persistent column (which sounds like oxymoron, but isn't).