I would like to insert in a table some pieces of code. For example:
table:
create table [tbl_cfg](
[tabid] [int] IDENTITY(1,1) NOT NULL,
cust_code nvarchar(max) NULL
) ON [PRIMARY]
Insert into tbl_cfg(cust_code)
select ' this is the first line
this is the second line'
My problem is that when I do this, sql automatically flatterns my code i.e. any \n is replaced with spaces.
If I insert it with Edit top 200 rows and I just paste the code, only the first line is inserted.
UPDATE:
In order to test this:
select * from tbl_cfg
copy the code and paste it in another window
According my experience about this issue:
Your strings with \n is still in the original format in sql table, but when you do select it is presented in a single line.
However, for example if you put the string to html code, you'll see \n is still there.
check http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in-code/
That's because you aren't seeing the result in text mode.
See this query and view the results with "Results to Text" checked and unchecked.
Related
we created a snowflake table as shown and loaded data into into from flat file using copy into command
create or replace table temp.T_ERROR
(
ID NUMBER(38,0) Primary Key,
ERROR varchar(4) collate 'en-rtrim' NOT NULL,
)
so we saw rtrimmed values in ERROR then we tried to transfer these results into another snowflake table with no collate option set on this table
create or replace table DATA.T_ERROR_1
(
ID NUMBER(38,0) Primary Key,
ERROR varchar(4) NOT NULL,
)
ISSUE:
the DATA.T_ERROR_1 table is not getting the trimmed values from temp table instead its getting un-trimmed values which are in the original flat file
is there any other ways i can do this transfer which doesnt involve me writing rtrim ltrim or trim or every column
None of your tables have trimmed data. It only appears so in certain circumstances.
The table temp.T_ERROR has trimmed comparison semantics, and that means it compares & sorts as if it was trimmed. But assignment is not comparison, and the original value in temp.T_ERROR (which is space padded) is copied into the new table DATA.T_ERROR_1. You can check that the spaces are there with eg
SELECT '"'||ERROR||'"', LENGTH(ERROR) FROM temp.T_ERROR
As Mike Walton says elsewhere, if you have a chance to trim the spaces before the data enters Snowflake, your problems may be solved. If however you are porting an application that relies heavily on CHAR behaviour, you might be better off defining COLLATE for all the CHAR columns.
I've tested on other databases (ie Oracle) and it behaves the same way as Snowflake: if you copy from CHAR to VARCHAR you get the padding spaces, too.
I've been banging my head against a brick wall for this for ages.
I am trying to query a table in SQL Express 2010. There are about ten fields in the table. One of the fields is a text field. Some of these have text in them, some have none (I am presuming that they are empty rather than null because querying with Is Null returns an empty set). I want to return the records which have text in this field and not those which are empty. I am guessing that they are empty rather than a blank space.
I have tried the NullIf and IsNull combinations I have seen posted in a few forums but the syntax in these are causing errors. When I put in ' ' as the empty string it is highlighted in red as an error and executing the query just returns an error about can not find such and such with this column name. Sorry I don't have the exact phrase, I'm also having problems with a monitor, etc, etc...
Hope you can help, let me know if you need any more info.
Thanks!
This bit of code shows how to handle NULL and/or "emptry string" text fields:
CREATE TABLE #TextTest (
ID INT IDENTITY,
TextCol TEXT
)
--Add 2 rows with data, 1 with NULL, 1 with "empty string".
INSERT INTO #TextTest (TextCol)
VALUES ('123'),('456'), (NULL), ('')
--This should succeed, but returns the one row with the "empty string".
SELECT *
FROM #TextTest
WHERE TextCol IS NOT NULL
--This should fail
SELECT *
FROM #TextTest
WHERE TextCol <> ''
--This should succeed.
SELECT *
FROM #TextTest
WHERE CAST(TextCol AS VARCHAR(MAX)) <> ''
--Clean up temp table when finished.
--DROP TABLE #TextTest
NOTE: ntext, text, and image data types will be removed in a future version of Microsoft SQL Server. Avoid using these data types in new development work, and plan to modify applications that currently use them. Use nvarchar(max), varchar(max), and varbinary(max) instead.
I am attempting to load a tab delimited text file which contains a column of values which happen to look exactly like a date, but aren't. It appears that the CSVREAD command scans the row, converts the text value in the column to a java.Sql.Date, and then sees that the target column is a VARCHAR and executes toString() to obtain the value...which is exactly NOT what I need. I actually need the raw unconverted text with no date processing whatsoever.
So, is there some way to turn off "helpful date-like column conversion" in the CSVREAD command?
Here's the simplest case I can make to demonstrate the undesired behavior:
CREATE TABLE x
(
name VARCHAR NOT NULL
value VARCHAR
) AS
SELECT * CSVREAD('C:\myfile.tab', null, 'UTF-8', chr(9))
;
The file contains three rows, a header and two records of values:
name\tvalue\n
x\t110313\n
y\t102911\n
Any assistance on how I can bypass the overhelpful part of CVSREAD would be greatly appreciated. Thank you.
(It seems you found this out yourself, but anyway):
For CSVREAD, all columns are strings. The CSVREAD function or the database do not try to convert values to a date, or in any other way try to detect the data type. The database only does what you ask it for, which is read the data as a string in your case.
If you do want to convert a column to a date, you need to do that explicitly, for example:
CREATE TABLE x(name VARCHAR NOT NULL, value TIMESTAMP) AS
SELECT *
FROM CSVREAD('C:\myfile.tab', null, 'UTF-8', chr(9));
If non-default parsing is needed, you could use:
CREATE TABLE x(name VARCHAR NOT NULL, value TIMESTAMP) AS
SELECT "name", parsedatetime("value", "M/d/y") as v
FROM CSVREAD('C:\myfile.tab', null, 'UTF-8', chr(9));
For people who don't have headers in there csv files the example could be like this:
CREATE TABLE x(name VARCHAR NOT NULL, value TIMESTAMP) AS
SELECT "0", parsedatetime("1", 'd-M-yyyy') as v
FROM CSVREAD('C:\myfile.tab', '0|1', 'UTF-8', '|');
Beware of the single quotes around the date format. When I tried the example from Thomas it gave me an error using H2:
Column "d-M-yyyy" not found; SQL statement:
My csv files:
firstdate|13-11-2013\n
seconddate|14-11-2013
table on external database (when I click modify) states that row A is a varchar(10) but when I look at the data there is obviously many more characters in it. How is this possible?
This concerns me because when I pull data from that row, I only get 10 characters, and the rest is cut off. I am not allowed to modify the external database tables.
How is this possible?
The column was probably originally a varchar(30) and was subsequently altered to varchar(10). I assume data has been written since the change to varchar(10), which makes this a true mess. If altering the column back to a length of 30 is not possible, I would investigate the implications of truncating the old data to 10 characters.
Update
run the following statement to confirm the column length:
select character_maximum_length
from information_schema.columns
where table_name='tablename' and COLUMN_NAME='columnname'
Update 2:
select max(len(column_name))
from tablename
I'm trying to investigate when & why certain rows are getting deleted in a SQL 2005 database. I've started building a trigger to log some information when a row is deleted.
My trigger is activated when row(s) are deleted from a certain table. I have it set up to log a timestamp in another logging table when the delete occurs. I'd also like to log the data that was deleted, but would prefer not to hassle with writing code for each field and value.
I know when data is deleted it can be seen (temporarily) in the "Deleted" table in SQL Server. So right after a delete, I could "SELECT * FROM Deleted" and see the data. I would like to take the contents of this table, and turn it into one large text blob that I can just save into a TEXT field in my logging table.
So... in simpler terms, is there a way I can take a recordset of one or more rows and turn it into a single string variable? all within SQL commands in my trigger? Bonus points if I can include column names.
Thanks
I would stay away from anything that would run too long when working in a trigger. That includes some query just to determine a static table layout (because you don't want to write the code yourself) so you can build a string.
I do this type of thing all the time, but mostly with stored procedure parameters. I have most of this in a template I use.
create this function, will display the column nicely within quotes or show NULL:
CREATE FUNCTION [dbo].[QuoteNull]
(
#InputStr varchar(8000) --value to pad
)
RETURNS
varchar(8000)
AS
/*
TEST WITH:
----------
PRINT ' dbo.QuoteNull(null) ->'+dbo.QuoteNull(null)+'<-'
PRINT ' dbo.QuoteNull(''apple'') ->'+dbo.QuoteNull('apple')+'<-'
PRINT ' dbo.QuoteNull(123) ->'+dbo.QuoteNull(123)+'<-'
PRINT ' dbo.QuoteNull(GETDATE()) ->'+dbo.QuoteNull(GETDATE())+'<-'
PRINT ' dbo.QuoteNull(GETDATE()) ->'+dbo.QuoteNull(CONVERT(varchar(23),GETDATE(),121))+'<-'
*/
BEGIN
RETURN COALESCE(''''+#InputStr+'''','null')
END
GO
paste this into your code:
INSERT INTO YourLogTable
(xxx,yyy,zzz,ColumnTextValue)
SELECT
xxx,yyy,zzz,'values:'
+' '+RTRIM('ColumnNameInt ')+'='+dbo.QuoteNull( ColumnNameInt )
+', '+RTRIM('ColumnNameVarchar ')+'='+dbo.QuoteNull( ColumnNameVarchar )
+', '+RTRIM('ColumnNameChar ')+'='+dbo.QuoteNull( ColumnNameChar )
+', '+RTRIM('ColumnNameDate ')+'='+dbo.QuoteNull(CONVERT(varchar(23),ColumnNameDate ,121))
FROM DELETED
make sure you have one row for each column in your table (if you have more just delete the extra ones later), if you want to see any dates in detail, use the convert as shown above.
run this query:
select sc.name
FROM syscolumns sc INNER JOIN sysobjects so ON sc.id = so.id
where UPPER(so.name)=UPPER('YourTableName') order by sc.colorder desc
take the output in SQL Server Management Studio (within text output mode), and do ALT-LEFT_Click-Drag a square over the column names, and copy this column based selection.
Go back to your code and ALT-Click-Drag a square over the complete "ColumnName..." values in the left column of the insert statement and paste. If you made a column selection, it will replace the column only and leave the code unchanged to the left and right. Do the same thing for the "ColumnName..." values in the right of the insert and you now have an INSERT that will build the data you want but will not waste too much time in the trigger.