I have a column of type timestamp which updates every time record updated.
We have some specific logic for syncronizing data and I'd like to store timestamp's value in other table so I can compare to source later. Can't make new column of type timestamp as it's auto-updated.
Which SQL type should I use in TableB for maximum performance and quicker CASTs on comparisons?
Taken from the docs
timestamp is the synonym for the rowversion data type and is subject
to the behavior of data type synonyms. In DDL statements, use
rowversion instead of timestamp wherever possible. For more
information, see Data Type Synonyms (Transact-SQL).
and
The timestamp syntax is deprecated.
and
Is a data type that exposes automatically generated, unique binary
numbers within a database. rowversion is generally used as a mechanism
for version-stamping table rows. The storage size is 8 bytes.
So putting this together: Think of TIMESTAMP (which should be ROWVERSION) as a meaningless 8-byte binary. If you really want to do something with it, you can store it as 8-byte binary or you can convert it to a type with a length of 8 bytes. In this case I'd suggest BIGINT.
First, understand that timestamp is NOT a value of type date and time, but rather a unique identifier based on this type of data.
I suggest you review the documentation Date and Time Data Types and Functions (Transact-SQL) and choose the type of data that best suits your needs. This could be DATETIME2, DATETIMEOFFSET, DATETIME
Related
I'm using SQL Server 2012 Enterprise. I have a requirement where I've to store data with DATETIME2 datatype in SSIS Variable. Unfortunately, SSIS variables don't have that data type.
If I'm storing it into datetime data type, I'm losing information. Can anyone help in giving workaround?
PS: My source system is SQL Server 2012 as well and I'm reading the data from column with datetime2 datatype.
SSIS, at least currently, has a "known" shortfall in that the variable value type, DateTime only has a precision to the second; effectively the same as a datetime2(0). If you therefore need to store anything more accurate that a second, such as if you are using datetime and the 1/300 of a second is important or if you are using datetime2 with a precision of 1 or more, the value type DateTime, will not serve your goal.
A couple of different options are therefore to store the value of as a String or numerical value. This does, however, come with it's own problems; most and foremost that neither of these datatypes are date and time datatypes.
It therefore depends what your goal is. I would most likely make use of a String datatype and ensure it has the ISO format ('yyyy-MM-ddThh:mm:ss.nnnnnnn'). If you're then using something like a T-SQL Task you can pass your variable as normal to the task and the data engine will interpret the literal string as a datetime2(7) (or whichever literal precision you used).
I have a very simple data structure with an integer primary key and an "xml" column stored as ntext. How can I update specific nodes of the xml column stored as ntext?
The ntext data type is problematic to say the least.
As marc_s wrote in his comments, this type is deprecated, and even if it wasn't, it's the wrong data type to use for storing XML data.
The XML data type has been around since at least the 2012 version, and you should really consider changing your database structure to use it instead of the deprecated ntext.
If changing the database structure is impossible, then you will have to select the value, try to convert it into a usable type (since ntext doesn't even supports the replace function), manipulate the data, and then convert it back to ntext and update the row.
I used the PRAGMA table_Info('table_name') to get the table names,field data type and other info about the table,it's giving me the expected values but when it comes to views the field data type returned is always "numeric". What might be the cause of this problem?...Is there other ways to get the field data type from a view? please help
I'm guessing it's a by-product of the fact that columns aren't really strongly typed in SQLite. While you can declare a type for a column, it won't prevent you from putting data of other types into that column. In other words, the data type is associated with the individual field rather than the column it's in. The specifics of how types are determined vary a bit depending on which version of SQLite you're using:
SQLite 2:
http://www.sqlite.org/datatypes.html
SQLite 3:
http://www.sqlite.org/datatype3.html
I have few questions on what data types to use and how to define some fields from my site. My current schema is in MySQL but in process of changing to PostregSQL.
First & Last name -> Since I have multi-lang, tables all support UTF-8, but do i need to declare them as nvarchar in-case a user enters a Chinese name? If so, how do i enforce field validation if it is set to accept alphabets only as i assume those are English alphabets and not validating for valid chinese or arabic alphabets? And i don't think PostregSQL supports nvarchar anyways?
To store current time line - > Example I work in company A from Jan 2009 to Present. So i assume there will be 3 field for this: timeline_to, timeline_from, time_line present where to & from are month/year varchars and present is just a flag to set the current date?
User passwords. i am using SHA 256 + salting. so i have 2 fields declared as follows:
password_hash - varchar (64)
password_salt- varchar (64)
Does this work if the user password needs to be between 8 and 32 chars long?
birth time -> I need to record birth time for the application to calculate some astrological values. so that means hour, minute and am/pm. So best to store these are 3 separate single select lists with varchar or use a time data type in the back end and allow users to use single select list in front end?
Lastly for birth month and year only, are these int or varchar if i store them in separate rows? They all have primary keys of int for reporting purposes so int makes more sense? or should i store them in 1 field only as date type?
NCHAR, not NVARCHAR.
Never make anything variable that you can make fixed; it is an added burden to pack/unpack on every access. Which means never, ever use var for indexed columns, you will have a very sluggish index. Disk space is cheap these days.
you need a Language column at the Person level that tells you what language to use in your various parsing and validation requirements.
Let's say you have Person, Employer, and Employment tables. The columns you discuss are in Employment.
you need a StartDate column and EndDate column, they are DATETIME datatype.
You do not need "present" as a separate column. "Present" is always the value of the newest Employment row, unless set to something different. Set a Default of the highest date the db can handle, eg. 9999-12-31; which can be overridden by an explicit entry.
No. You only need one CHAR(256) column. Hank has explained it.
For any component of a date or time, use the DATETIME datatype. That is what it is there for. The database handles it consistently, and indexes it perfectly. You perform DATE arithmetic on it, using db various functions(). And you avoid all the problems of coding it as INTs, etc (no invalid dates or times allowed).
BirthDateTime is one DATETIME column.
I have no idea, never dealt with that field much.
You might consider allowing NULL here and using it as a special meaning for Present. If your application logic sees a non-null start date and a null end date, you can infer this. If they are both NULL, then no information can be inferred.
Since you're hashing, you'll always get a 256-bit hex string as the output no matter what the input is, so yes, 8-32 character passwords will all work.
Use a DATETIME in the backend. You can do things like MONTH() to extract the parts right in your SQL syntax. Of course, you'll have to format the date just right for SQL to accept it, but that's not too hard.
Again, all extractable with the DATETIME functions in SQL.
A bit of background first. My company is evaluating whether or not we will migrate our Informix database to Oracle 10g. We have several ESQL/C programs. I've run some through the Oracle Migration workbench and have been muddling through some testing. Now I've come to realize a few things.
First, we have dynamic sql statements that are not handling null values at all. From what I've read, I either have to manually modify the queries to utilize the nvl( ) function or implement indicator variables. Can someone confirm if manual modifications are necessary? The least amount of manual changes we have to make to our converted ESQL/C programs, the better.
Second, we have several queries which pull dates from various tables etc., and in Informix dates are treated as type long, the # of days since Dec 31st, 1899.
In Pro*C, what format is a date being selected as? I know it's not numeric because I tried selecting date field into my long variable and get Oracle error stating "expected NUMBER but got a DATE". So I'm assuming we'd have to modify how we are selecting date fields - either select a date field in a converted manner so it becomes a long (ie, # of days since 12/31/1899), or change the host variable to match what Oracle is returning (what is that, string?).
Ya. You will need to modify your queries as you described.
long is tripping you up. long has a different meaning in Oracle. There is a specific DATE type. Generally when selecting one uses the TO_DATE function with a format, to get the result as a VARCHAR2, in exactly the format you want.
Probably it didn't hit you yet but be aware that in Oracle empty VARCHAR2 fields are NULLs. I see no logic behind this (probably because I came from Informix land) - just keep it in mind. I think it is stupid - IMHO empty string is meaningful and different from NULL.
Either modify all your VARCHAR2 fields to be NOT NULL DEFAULT '-' or any other arbitrary value, or use indicatores in ALL your queries that return VARCHAR2 fields, or always use NVL().
In order to convert the oracle dates (which are store in Oracle internal format) into a long integer, you will need to alter your queries. Use the following formula for your dates:
to_number (to_char (date_column, 'J')) - to_number(to_char(to_date('12/31/1899', 'MM/DD/YYYY'), 'J'))
The Oracle system 'J' (for Julian date) format is a count of number of days since December 31, 4712BC. If you want to count from a later date, you'll need to subtract off the Julian day count of that later date.
One suggestion: instead of altering all of your queries in your programs (which may create problems and introduce bugs), create a set of views in a different schema. These views would be named the same as all the tables, with all the same columns, but include the NVL() and date() formulas (like above). Then point your application at the view schema rather than the base table schema. Much less testing and fewer places to missing something.
So for example, put all your tables into a schema called "APPS_BASE" (defined by the user "APPS_BASE". Then create another schema/user called "APPS_VIEWS". In the APPS_VIEWS create a view:
CREATE OR REPLACE VIEW EMP AS
SELECT name, birth_date
FROM APPS_BASE.EMP;