I have strange problem in an AWS RDS SQL Server database I have spun up and I can't figure out what is going on.
Test 1
create table #tmp
(test varchar(10) null)
insert into #tmp
select 'asfsadfasdsafdafas'
select * from #tmp
drop table #tmp
Results in:
Msg 8152, Level 16, State 14, Line 5
String or binary data would be truncated.
(0 row(s) affected)
Test 2
set ANSI_WARNINGS OFF
create table #tmp1
(test varchar(10) null)
insert into #tmp1
select 'asfsadfasdsafdafas'
select * from #tmp1
drop table #tmp1
Results in:
------------------
asfsadfasd
When I look at the database properties it says that ANSI Warnings Enabled is set to FALSE, however, the database does not appear to be behaving as expected.
Any help would be appreciated.
EDIT:
Another Example might help
ALTER DATABASE test_db
set QUOTED_IDENTIFIER OFF
go
select "hello"
Results in:
Msg 207, Level 16, State 1, Line 5
Invalid column name 'hello'.
Thanks
--The Issue Occur Because of Length Of Datatype
create table #tmp1
(test varchar(50) null)
insert into #tmp1
select 'asfsadfasdsafdafas'
select * from #tmp1
drop table #tmp1
--==============================
When create or alter SQL object like Stored Procedure, User Defined Function in Query Analyzer, it is created with following SQL commands prefixed and suffixed. What are these – QUOTED_IDENTIFIER ON/OFF and ANSI_NULL ON/OFF?
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO--SQL PROCEDURE, SQL FUNCTIONS, SQL OBJECTGO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
ANSI NULL ON/OFF:
This option specifies the setting for ANSI NULL comparisons. When this is on, any query that compares a value with a null returns a 0. When off, any query that compares a value with a null returns a null value.
QUOTED IDENTIFIER ON/OFF:
This options specifies the setting for usage of double quotation. When this is on, double quotation mark is used as part of the SQL Server identifier (object name). This can be useful in situations in which identifiers are also SQL Server reserved words.
Related
I just enabled change tracking by turning on ALLOW_SNAPSHOT_ISOLATION, executing this query to turn on change tracking for the database
ALTER DATABASE [DatabaseName]
SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS,AUTO_CLEANUP = ON)
and by finally enabling it on the table
ALTER TABLE [TableName]
ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = OFF)
Now when I call
SELECT *
FROM CHANGETABLE(CHANGES, 0)
I get this error message:
Invalid object name 'CHANGETABLE'.
The database version is SQL Server 2012. How can CHANGETABLE be invalid and how can I make it work? I assumed it would work out of the box because it's a system function. It's even highlighted in SQL Server Management Studio. I modified a little bit of data between turning on change tracking and calling CHANGETABLE().
The correct syntax is
SELECT * FROM CHANGETABLE(CHANGES MyTableName,#last_version) as SomeAlias
This is shown in the documentation examples :
DECLARE #last_sync_version bigint;
SET #last_sync_version = <value obtained from query>;
SELECT [Emp ID], SSN,
SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION,
SYS_CHANGE_COLUMNS, SYS_CHANGE_CONTEXT
FROM CHANGETABLE (CHANGES Employees, #last_sync_version) AS C;
Forgetting the table name results in Invalid object name 'CHANGETABLE'
Forgetting the table alias results in A table returned by the CHANGETABLE function must be aliased.
I am trying to insert the data of a stored procedure into a temp table like below
CREATE TABLE #CustomTable3HTML
(
ItemId varchar(30),
ItemId1 varchar(30)
)
INSERT INTO #CustomTable3HTML
EXEC SalesDeals.dbo.prGetDealProposalDetail 17100102, 1
but I am getting this error
Msg 8164, Level 16, State 1, Procedure prGetDealProposalDetail, Line 138 [Batch Start Line 1]
An INSERT EXEC statement cannot be nested.
I figured this is because the stored procedure already has an insert into clause defined and I found out that it can be used only once in the calling chain.
So I started looking for other options and found out about OpenRowSet which I am using as below
SELECT *
INTO #CustomTable3HTML
FROM OPENROWSET('SQLOLEDB','Server=Demo\Demo;Trusted_Connection=Yes;Database=SalesDeals',
'SET NOCOUNT ON;SET FMTONLY OFF;EXEC SalesDeals.dbo.prGetDealProposalDetail 17100102,1')
I am getting an error when I run this SQL command
Access to the remote server is denied because no login-mapping exists.
It works fine when I use a higher level account like sysadmin but fails with the other account which is a normal db owner on the database where I am running this SQL.
There is work around of this. It's not beautiful, but it will work.
In our outer query define a table:
CREATE TABLE #CustomTable3HTML
(
ItemId varchar(30),
ItemId1 varchar(30)
)
Change the procedure adding the following code at the end:
IF OBJECT_ID('tempdb..#CustomTable3HTML')
BEGIN
INSERT INTO #CustomTable3HTML
SELECT ....
END
ELSE
BEGIN
SELECT ....
END
After executing the stored procedure you will have the data in table.
Note: the highest linked question does not solve the problem for system stored procedures, but it's close. With help of the commenters, I came to a working answer.
Trying to use statements such as the following for sp_spaceused, throws an error
SELECT * INTO #tblOutput exec sp_spaceused 'Account'
SELECT * FROM #tblOutput
The errors:
Must specify table to select from.
and:
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
When I fully declare a table variable, it works as expected, so it seems to me that the stored procedure does return an actual table.
CREATE TABLE #tblOutput (
name NVARCHAR(128) NOT NULL,
rows CHAR(11) NOT NULL,
reserved VARCHAR(18) NOT NULL,
data VARCHAR(18) NOT NULL,
index_size VARCHAR(18) NOT NULL,
unused VARCHAR(18) NOT NULL)
INSERT INTO #tblOutput exec sp_spaceused 'Response'
SELECT * FROM #tblOutput
Why is it not possible to use a temp table or table variable with the result set of EXECUTE sp_xxx? Or: does a more compact expression exist than having to predefine the full table each time?
(incidentally, and off-topic, Googling for the exact term SELECT * INTO #tmp exec sp_spaceused at the time of writing, returned exactly one result)
TL;DR: use SET FMTONLY OFF with OPENQUERY, details below.
It appears that the link provided by Daniel E. is only part of the solution. For instance, if you try:
-- no need to use sp_addlinkedserver
-- must fully specify sp_, because default db is master
SELECT * FROM OPENQUERY(
[SERVERNAME\SQL2008],
'exec somedb.dbo.sp_spaceused ''Account''')
you will receive the following error:
The OLE DB provider "SQLNCLI10" for linked server "LOCALSERVER\SQL2008" supplied inconsistent metadata for a column. The name was changed at execution time.
I found the solution through this post, and then a blog-post on OPENQUERY, which in turn told me that until SQL2008, you need to use SET FMTONLY OFF. The final solution, which is essentially surprisingly simple (and easier to accomplish since there is no need to specify a loopback linked server), is this:
SELECT * FROM OPENQUERY(
[SERVERNAME\SQL2008],
'SET FMTONLY OFF
EXEC somedb.dbo.sp_spaceused ''Account''')
In addition, if you haven't set DATA-ACCESS, you may get the following error:
Server 'SERVERNAME\SQL2008' is not configured for DATA ACCESS.
This can be remedied by running the following command:
EXEC sp_serveroption 'SERVERNAME\SQL2008', 'DATA ACCESS', TRUE
We cannot SELECT from a stored procedure thats why SELECT * INTO ..Exec sp_ will not work.
To get the result set returned from a store procedure we can INSERT INTO a table.
SELECT INTO statement creates a table on fly and inserts data from the source table/View/Function. The only condition is source table should exist and you should be able to Select from it.
Sql Server doesn't allow you to use SELECT from sp_ therefore you can only use the INSERT INTO statement when executing a stored procedure this means at run time you can add the returned result set into a table and Select from that table at later stage.
INSERT INTO statement requires the destination table name, An existing table. Therefore whether you use a Temp Table, Table variable or Sql server persistent table you will need to create the table first and only they you can use the syntax
INSERT INTO #TempTable
EXECUTE sp_Proc
Using [YOUR DATABASE NAME]
CREATE TABLE [YOURTABLENAME]
(Database_Name Varchar(128),
DataBase_Size VarChar(128),
unallocated_Space Varchar(128),
reserved Varchar(128),
data Varchar(128),
index_size Varchar(128),
unused Varchar(128)
);
INSERT INTO dbo.[YOUR TABLE NAME]
(
Database_Name,
DataBase_Size,
unallocated_Space,
reserved,
data,
index_size,
unused
)
EXEC sp_spaceused #oneresultset = 1
--To get it to return it all as one data set add the nonresultset=1 at the end and viola good to go for writing to a table. :)
I have a problem with my script SQL, please help me.
Ex:
I have a insert statments:
INSERT INTO CUSTOMER (Code, Date) VALUES (1, GETDATE());
When I execute this insert, retuns the follow message:
"Msg 1934, Level 16, State 1, Server
HENRIQUE-PC, Line 5 INSERT failed
because the following SET options have
incorrect settings: 'QUOTED
_IDENTIFIER'. Verify that SET options are correct for use with
indexed views and /or indexes on
computed columns and/or filtered
indexes and/or query notificatio ns
and/or XML data type methods and/or
spatial index operations.".
Now, when I used SET QUOTED_IDENTIFIER ON, my insert is executed with success.
Ex:
SET QUOTED_IDENTIFIER OFF
GO
INSERT INTO CUSTOMER (Code, Date) VALUES (1, GETDATE());
SET QUOTED_IDENTIFIER ON
GO
(1 row(s) affected)
What relationship betwhen GETDATE() and QUOTED IDENTIFIER?
Why I need to use QUOTED IDENTIFIER in this case?
I believe it is because of getdate. Why?
Thanks.
Henrique Melicio
Henrique,
The reason you're getting that error is not related to GETDATE(), it has to do with indexes on columns from your CUSTOMER table. This bit from SQL Server 2008's SET Statements (Transact-SQL) document explains the issue in more detail:
When you are creating and manipulating
indexes on computed columns or indexed
views, the SET options ARITHABORT,
CONCAT_NULL_YIELDS_NULL,
QUOTED_IDENTIFIER, ANSI_NULLS,
ANSI_PADDING, and ANSI_WARNINGS must
be set to ON. The option
NUMERIC_ROUNDABORT must be set to OFF.
If any one of these options is not set
to the required values, INSERT,
UPDATE, DELETE, DBCC CHECKDB and DBCC
CHECKTABLE actions on indexed views or
tables with indexes on computed
columns will fail. SQL Server will
raise an error listing all the options
that are incorrectly set. Also, SQL
Server will process SELECT statements
on these tables or indexed views as if
the indexes on computed columns or on
the views do not exist.
I'm executing stored procedures using SET FMTONLY ON, in order to emulate what our code generator does. However, it seems that the results are cached when executed like this, as I'm still getting a Conversion failed error from a proc that I have just dropped! This happens even when I execute the proc without SET FMTONLY ON.
Can anyone please tell me what's going on here?
Some statements will still be executed, even with SET FMTONLY ON. You "Conversion failed" error could be from something as simple as a set variable statement in the stored proc. For example, this returns the metadata for the first query, but throws an exception when it runs the last statement:
SET FMTONLY on
select 1 as a
declare #a int
set #a = 'a'
As for running a dropped procedure, that's a new one to me. SQL Server uses the system tables to determine the object to execute, so it doesn't matter if the execution plan is cached for that object. If you drop it, it is deleted from the system tables, and should never be executable. Could you please query sysobjects (or sys.objects) just before you execute the procedure? I expect you'll find that you haven't dropped it.
This sounds like a client-side error. Do you get the same message when running through SQL Management Studio?
Have you confirmed that there isn't another procedure with the same name that's owned by a different schema/user?
DDL statements are parsed, but ignored when run if SET FMTONLY ON has been executed on the connection. So if you drop a proc, table, etc when FMTONLY is ON, the statement is parsed, but the action is not executed.
Try this to verify
SET FMTONLY OFF
--Create table to test on
CREATE TABLE TestTable (Column1 INT, Column2 INT)
--insert 1 record
INSERT INTO TestTable (Column1, Column2)
VALUES (1,2)
--validate the record was inserted
SELECT * FROM TestTable
--now set format only to ON
SET FMTONLY ON
--columns are returned, but no data
SELECT * FROM TestTable
--perform DDL statement with FMTONLY ON
DROP TABLE TestTable
--Turn FMTONLY OFF again
SET FMTONLY OFF
--The table was dropped above, so this should not work
SELECT * FROM TestTable
DROP TABLE TestTable
SELECT * FROM TestTable