I tried to execute this code and it worked o.k without the the stored procedure and with it, it made an error.
The error is:
Msg 102, Level 15, State 1, Procedure UV_MTBF, Line 251
Incorrect syntax near 'Event_'.
Is the stored procedure have a limitation in length?
can someone help me with my code?
edit*
my problem is with ' + QUOTENAME(#category,N'''') + N'
i want to add an integer from a variable that i received in the stored procedure. how can i do it?
enter code here:
CREATE PROCEDURE dbo.MTBFCalculation #Category int, #Action bit, #relateToParent bit
as
IF EXISTS (SELECT 1 FROM sys.objects WHERE [name] = '[dbo].[UV_MTBF]')
DROP VIEW [dbo].[UV_MTBF];
DECLARE #Event nvarchar(MAX) = N'
CREATE VIEW [dbo].[UV_MTBF]
as
with failureReportTable as (SELECT [ID] as failure_id
,[Login_ID]
,[Event_ID]
,[StartDate]
,[EndDate]
,DATEDIFF(Hour,[StartDate],[EndDate]) as eventDurationMin
,[IsRelevantForBI]
,[IsParallelReport]
,[ParentReportID]
,[IsPausedEvent]
,Case
When ParentReportID>0 Then 1 --Chiled
When IsParallelReport=1 Then 2 --Parent
Else 3 --not Parallel
End as ParallelStatus
FROM [TDM_Analysis].[dbo].[FailureReports]),
fullFailure as (select *, ROW_NUMBER() OVER (ORDER BY [StartDate] ) AS IDrow
from failureReportTable join [TDM_Analysis].[dbo].[UV_filteredLogins] as viewLogins on failureReportTable.Login_ID=viewLogins.ID
WHERE event_id IN (SELECT ID FROM [TDM_Analysis].[dbo].[Events] where EventCategory_ID=' + QUOTENAME(#category,N'''') + N')
and (ParallelStatus=3 or ParallelStatus=(case when ' + QUOTENAME(#relateToParent,N'''') + N'=1 then 2 else 1 end))),
--------------create first failure table------------------
failure_Event_1 as (select f1.failure_id as Event_1_Failure_ID
,f1.[Login_ID] as Event_1_Login_ID
,f1.[Event_ID] as Event_1_Event_ID
,f1.[StartDate] as Event_1_StartDate
,f1.[EndDate] as Event_1_EndDate
,f1.eventDurationMin as Event_1_eventDurationMin
--,f1.[IsRelevantForBI] as Event_1_IsRelevantForBI
--,f1.[IsParallelReport] as Event_1_IsParallelReport
-- ,f1.[ParentReportID] as Event_1_ParentReportID
-- ,f1.[IsPausedEvent] as Event_1_IsPausedEvent
,f1.[Test_Name] as Event_1_TestName
,f1.Phase_Name as Event_1_PhaseName
,f1.PressName as Event_1_PressName
,f1.PressType as Event_1_PressType
--,f1.[Operator] as Event_1_Operator
,f1.[LoginDate] as Event_1_LoginDate
,f1.[LogoutDate] as Event_1_LogoutDate
,f1.TimeDiff as Event_1_LoginDuration
,f1.IDrow+1 as row1
from fullFailure as f1),
--------------create second failure table------------------
failure_Event_2 as (select f1.failure_id as Event_2_Failure_ID
,f1.[Login_ID] as Event_2_Login_ID
,f1.[Event_ID] as Event_2_Event_ID
,f1.[StartDate] as Event_2_StartDate
,f1.[EndDate] as Event_2_EndDate
,f1.eventDurationMin as Event_2_eventDurationMin
-- ,f1.[IsRelevantForBI] as Event_2_IsRelevantForBI
-- ,f1.[IsParallelReport] as Event_2_IsParallelReport
-- ,f1.[ParentReportID] as Event_2_ParentReportID
-- ,f1.[IsPausedEvent] as Event_2_IsPausedEvent
,f1.[Test_Name] as Event_2_TestName
,f1.Phase_Name as Event_2_PhaseName
,f1.PressName as Event_2_PressName
,f1.PressType as Event_2_PressType
-- ,f1.[Operator] as Event_2_Operator
,f1.[LoginDate] as Event_2_LoginDate
,f1.[LogoutDate] as Event_2_LogoutDate
,f1.TimeDiff as Event_2_LoginDuration
,f1.IDrow as row2
from fullFailure as f1),
------------- join two failure tabels and calculating MTTR-mean time to repair (duration of failue), MTTF-mean time to failue( end of one until start of a new one), MTBF-mean time between failue (from start of a failure to start of a new one)--------------------
joinFailures as (select *, Event_1_eventDurationMin as MTTR
,CASE
When isnull(f2.row2,0)=0 then DATEDIFF(HOUR,f1.Event_1_EndDate,f1.Event_1_LogoutDate)
WHEN f1.Event_1_Login_ID=f2.Event_2_Login_ID THEN DATEDIFF(HOUR,f1.Event_1_EndDate,f2.Event_2_StartDate)
When (select TOP 1 sum(timediff)
from [TDM_Analysis].[dbo].[UV_filteredLogins]
where logindate>f1.Event_1_LogoutDate and logindate<f2.Event_2_LoginDate) is null then DATEDIFF(HOUR,f1.Event_1_EndDate,f1.Event_1_LogoutDate)+DATEDIFF(HOUR,f2.Event_2_LoginDate, f2.Event_2_StartDate)
ELSE
(select TOP 1 sum(timediff)+DATEDIFF(HOUR,f1.Event_1_EndDate,f1.Event_1_LogoutDate)+DATEDIFF(HOUR,f2.Event_2_LoginDate, f2.Event_2_StartDate)
from [TDM_Analysis].[dbo].[UV_filteredLogins]
where logindate>f1.Event_1_LogoutDate and logindate<f2.Event_2_LoginDate)
END AS MTTF
from failure_Event_1 as f1 left join failure_Event_2 as f2 on f1.row1=f2.row2),
positiveJoinFailure as (select * from joinFailures where MTTF>=0)
---- select calculation table order by ascending time----------
select * --Event_1_Failure_ID,Event_2_Failure_ID,MTTR,MTTF, MTTR+MTTF as MTFB
from positiveJoinFailure
--order by row1
';
--------------------------------------------------------Action------------------------------------------------------------------------------
if #Action=1
begin
EXEC sp_executesql #Event;
end
for this part of your query
where EventCategory_ID=' + QUOTENAME(#category,N'''') + N')
2 option here, you convert the value of #category to string and then concatenate with the dynamic query
where EventCategory_ID=' + convert(varchar(10), #category)
OR, you pass the value in as a parameter.
for this option, you specify #category in the dynamic query
where EventCategory_ID= #category
and (ParallelStatus=3 ....
and you pass the value in at sp_executesql
EXEC sp_executesql #Event, N'#category int', #category
By the way, Option 2 is the preferred method when using dynamic query
Related
I'm getting the following error
Conversion failed when converting date and/or time from character string
I can't get it to run properly please help me, here is my code (don't shame my loop i just need it to work).
The thing is i have a closed list with contracts IDs and a table with different dates and dates called #PERIODO it contains datetime type.
WHILE (SELECT TOP 1 FECHA1 FROM #PERIODO) > 0
BEGIN
SET #MES_ANTERIOR = (SELECT TOP 1 FECHA1 FROM #PERIODO ORDER BY FECHA1 ASC)
SET #MES_EN_CURSO = (SELECT TOP 1 B.FECHA1 FROM (SELECT TOP 2 A.FECHA1 FROM #PERIODO A ORDER BY FECHA1 ASC ) B ORDER BY B.FECHA1 DESC)
SET #MES_3 = (SELECT TOP 1 FECHA3 FROM #PERIODO ORDER BY FECHA1 ASC)
SET #MES_4 = (SELECT TOP 1 B.FECHA3 FROM (SELECT TOP 2 A.FECHA3 FROM #PERIODO A ORDER BY FECHA3 ASC ) B ORDER BY B.FECHA3 DESC)
SET #MES_ANT = LEFT(CONVERT(VARCHAR(8),#MES_ANTERIOR,112),8) -- SELECT #MES_ANT
SET #MES_CURR = LEFT(CONVERT(VARCHAR(8),#MES_EN_CURSO,112),8) -- SELECT #MES_CURR
EXEC('IF OBJECT_ID(''WORK.DBO.OPERACIONES_ABIF_'+#MES_CURR+''', ''U'') IS NOT NULL
DROP TABLE WORK.DBO.OPERACIONES_ABIF_'+#MES_CURR+' ')
SET #SQL1 = 'SELECT DISTINCT
A.*
INTO WORK.DBO.OPERACIONES_ABIF_'+#MES_CURR+'
FROM BDGESTION.DBO.BASE_RIESGOS_PROD_ALTAIR_'+#MES_CURR+' A WHERE '
SET #SQL2 = ' A.NUM_OPERACION IN (
SELECT
B.NUM_CONTRATO
FROM (
SELECT NUM_CONTRATO
FROM
( SELECT * FROM #OPER WHERE FECHA_INICIO IS NOT NULL) H
WHERE H.FECHA_INICIO < CAST(CONVERT(VARCHAR(12),'+#MES_EN_CURSO+',23) AS VARCHAR )
AND H.FECHA_INICIO >= CAST(CONVERT(VARCHAR(12),'+#MES_ANTERIOR+',23) AS VARCHAR )
) B
WHERE
B.NUM_CONTRATO IS NOT NULL ) '
EXEC (#SQL1 + #SQL2)
DELETE FROM #PERIODO
WHERE FECHA1 = #MES_ANTERIOR
END
The problem would appear to be these lines:
WHERE H.FECHA_INICIO < CAST(CONVERT(VARCHAR(12), ' + #MES_EN_CURSO + ', 23) AS VARCHAR)
Presumably, you want the cast() outside the aggregation:
WHERE H.FECHA_INICIO < ' + CONVERT(VARCHAR(12), #MES_EN_CURSO + ', 23) + '
However, I don't recommend this as a solution. The correct solution is to pass the value in as a parameter. Your query is too complex (and messy) for me to attempt that. You should look at the documentation for sp_executesql on how to properly construct dynamic SQL with parameters.
I think you should print #SQL2 as you go through the loop so you can see the incorrect value.
It would be helpful to show how you declare #MES_EN_CURSO and declare #MES_ANTERIOR.
I want to convert the obtained query (below exposed, see:code) into a new table so I can compute and process the data more easily..
I know this question sounds stupid, but when I use:
SELECT X.*
INTO NewTable
FROM
(
SELECT .... complex query ....
FROM ...
...
) AS X
It sends me an error message, how am I supposed to enter my query into this code above mentioned..
Error:
Msg 156, Level 15, State 1, Line 10
Incorrect syntax near the keyword 'select'.
Msg 156, Level 15, State 1, Line 54
Incorrect syntax near the keyword 'from'.
Code:
SELECT *
INTO Price_to_book_valid
FROM
(
select *
from pricetobook
declare #sql nvarchar(max);
declare #fields nvarchar(max);
set #fields=stuff((select ',['+column0+']'
from dll_ptbv
where column0 not in ('Code','Mnemonic')
group by column0
order by case when column0='Name' then 0 else 3 end
,column0
for xml path('')
,type
).value('.','nvarchar(max)')
,1 ,1 ,'');
set#sql='select'+#fields
+ 'from (select column0
,column1
,sum(rn1*rn2) over(order by rn2) as rn
from (select column0
,column1
,case when column0=''Name'' then 1 else 0 end as rn1
,row_number() over(order by (select null)) as rn2
from dll_ptbv
) as a
) as a
pivot (max(column1) for column0 in ('+#fields+')) as p
order by [Name]';
execute sp_executesql #sql;
You coudl use a select INTO before column Name
SELECT * INTO NewTable
FROM
(
SELECT .... complex query ....
FROM ...
...
) p <<<<<<<< remove as
( you should remove as in as a) fist you should assign a table name and eventulally after you can use an alais
-- 14. SELECT INTO new table from dynamic stored procedure execution.
-- Dynamic stored procedure to temporary table
USE tempdb;
GO
-- SQL create dynamic stored procedure
CREATE PROCEDURE DynamicSprocToTempTable
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'SELECT top (5) * from AdventureWorks.Purchasing.PurchaseOrderHeader
ORDER BY NEWID()'
-- Dynamic SQL
EXEC Sp_executesql #SQL
END
GO
-- Test stored procedure
EXEC tempdb.dbo.DynamicSprocToTempTable
GO
-- Select into temporary table from OPENQUERY
-- SQL select into temp table
SELECT * INTO #poh
FROM Openquery(SERVERALPHA,'exec tempdb.dbo.DynamicSprocToTempTable')
GO
SELECT PurchaseOrderID, VendorID, OrderDate
FROM #poh
/* Results
PurchaseOrderID VendorID OrderDate
2662 50 2004-05-19 00:00:00.000
2454 44 2004-05-01 00:00:00.000
2547 96 2004-05-10 00:00:00.000
901 54 2003-10-13 00:00:00.000
2675 74 2004-05-22 00:00:00.000
*/
GO
Error:
Could not find stored procedure 'SELECT TOP 1 name FROM (SELECT TOP 5 name FROM sys.tables ORDER BY name DESC) as t ORDER BY name ASC'.
Code:
WHILE (#interval <= #max)
BEGIN
SET #SQL = 'SELECT TOP 1 name FROM (' +
SELECT TOP ' + convert(varchar(10), #interval) +
' name FROM sys.tables ORDER BY name DESC) as t ORDER BY name ASC'
EXEC #SQL
SELECT #interval = #interval + 1
END
Executing the following command on its own works properly:
SELECT TOP 1 name
FROM
(SELECT TOP 5 name
FROM sys.tables
ORDER BY name DESC) as t
ORDER BY
name ASC
Incrementing the inner TOP # manually and running the command without TSQL will rotate through each table properly. (This will eventually include a nested loop for Column, and another nested loop for a search within that column.)
That the command runs without the variable makes me think this is a scope issue. Shouldn't I be able to resolve this by inserting the list of table names into a temp table with a Primary Key of Seed 1, Increment 1 for a row_id, and then looping through the table via incrementing my #row_id = row_id?
Any suggestions?
It should be exec(#sql), I think
Is it possible to execute a SQL statement Stored in a Table, with T-SQL?
DECLARE #Query text
SET #Query = (Select Query FROM SCM.dbo.CustomQuery)
The statements that are stored in the table are ad-hoc statements which could be SELECT TOP 100 * FROM ATable to more complex statements:
Select
J.JobName As Job,
JD.JobDetailJobStart AS StartDate,
JD.JobDetailJobEnd AS EndDate,
(
SELECT (DATEDIFF(dd, JD.JobDetailJobStart, JD.JobDetailJobEnd) + 1) -(DATEDIFF(wk, JD.JobDetailJobStart, JD.JobDetailJobEnd) * 2) -(CASE WHEN DATENAME(dw, JD.JobDetailJobStart) = 'Sunday' THEN -1 ELSE 0 END) -(CASE WHEN DATENAME(dw, JD.JobDetailJobEnd) = 'Saturday' THEN -1 ELSE 0 END)
) AS NumberOfWorkingDays,
JD.JobDetailDailyTarget AS DailyTarget,
JD.JobDetailWeeklyTarget AS WeeklyTarget,
JD.JobDetailRequiredQTY AS RequiredQuantity,
(
Select SUM(sJL.JobLabourQuantityEmployees) From JobLabour sJL
) AS NumberOfEmployees,
(
Select
SUM((sEM.EmployeeDesignationDefaultRate * sJL.JobLabourQuantityEmployees)*8)*(SELECT (DATEDIFF(dd, JD.JobDetailJobStart, JD.JobDetailJobEnd) + 1) -(DATEDIFF(wk, JD.JobDetailJobStart, JD.JobDetailJobEnd) * 2) -(CASE WHEN DATENAME(dw, JD.JobDetailJobStart) = 'Sunday' THEN -1 ELSE 0 END) -(CASE WHEN DATENAME(dw, JD.JobDetailJobEnd) = 'Saturday' THEN -1 ELSE 0 END))
from EmployeeDesignation sEM
Inner join JobLabour sJL on sJL.EmployeeDesignationID = sEM.EmployeeDesignationID
) AS FullEmployeeRate
from Job J
Inner Join JobDetail JD on JD.JobID = J.JobID
Inner Join JobLabour JL on JL.JobID = J.JobID
WHERE J.JobActive = 0
I want to execute the #Query Variable that I declared from T-SQL. Is this possible? (I am running a MSSQL 2005 enviroment)
You can use
EXECUTE sp_executesql #Query
to run your T-SQL
Here's a link to the MS docn for SQL Server 2005
http://msdn.microsoft.com/en-us/library/ms188001%28v=sql.90%29.aspx
The previous answer allows you to run one statement, and is valid. The question was on how to run SQL Statements stored in a table, which I took as more than one statement being executed. For this extra step, there is a while loop involved to iterate through each statement that need to be run.
-- Author: Chad Slagle
DECLARE #Table table (RID BIGINT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
SQLText NVARCHAR(MAX) )
DECLARE #StatementMax INT
,#statementMin INT
,#isTest TINYINT = 1
,#SQLStatement NVARCHAR(MAX)
-- Insert SQL Into Temp Table
INSERT INTO #table (SQLText)
VALUES ('SELECT ##Version');
INSERT INTO #table (SQLText)
VALUES ('SELECT SERVERPROPERTY(''ProductVersion'')')
-- Get your Iterator Values
SELECT #statementMAX = MAX(RID), #statementMIN = MIN(RID) FROM #table
IF #isTest = 1 BEGIN SELECT *, #statementMax AS MaxVal, #StatementMin AS MinVal FROM #Table END
-- Start the Loop
WHILE #StatementMax >= #statementMin
BEGIN
SELECT #SQLStatement = SQLText FROM #table WHERE RID = #statementMin -- Get the SQL from the table
IF #isTest = 1 BEGIN SELECT 'I am executing: ' + #SQLStatement AS theSqlBeingRun, GETDATE(), #statementMin, #StatementMax END
ELSE
BEGIN
EXECUTE sp_ExecuteSQL #SQLStatement -- Execute the SQL
END
DELETE FROM #table WHERE RID = #statementMin -- Delete the statement just run from the table
SELECT #statementMIN = MIN(RID) FROM #Table -- Update to the next RID
IF #isTest = 1 BEGIN SELECT * FROM #table END
END
In Summary, I created a temp table and put some SQL in it, using a IDENTITY (RID) field to provide an iterator for the while loop. Then ran the while loop. In the example, you should return two views of your SQL Version. I built this on 2k8, and I hope it helps someone out of a jam one day..
We use a much simpler approach. Store the scripts (raw sql or stored procedure calls) in a table with a column containing an identifying code for said script. Use placeholders in your script for parameters. Any scripts that are used a lot can be "keyed" in your app or web config file. If scripts need to be executed in a specific order, put an ordinal column in the table. The actual "script" can then be pulled into a c# list or array, passed to a database class library and executed accordingly. This gives you dynamic control over your SQL and allows you to make changes on the database side for said scripts without recompiling your main application.
TRUNCATE TABLE AllTableUnion
DECLARE #Query2 Nvarchar(MAX)
SET #Query2='SELECT * FROM #UnionString t1)A'
INSERT INTO AllTableUnion
EXEC(#Query2)
DECLARE #Query4 Nvarchar(MAX)=(SELECT Query FROM AllTableUnion)
EXECUTE sp_ExecuteSQL #Query4
I have a similar situation I just can't get to work. I'd like to create a table, where we have a customer number, and the business rules used to determine codes for a variety of items. The table psudo looks like this:
| CustomerNumber | RuleName | Rule |
----------------------------------------------------------------------
| 12345 |ShippingCharged | iif(id.ItemID in (1,2,3,4,5,6) AND
cod.Code IN (5,6,7,8),1,0)
| 99999 |ShippingCharged | iif(id.ItemID in (1,2,3,7,9,10) AND
cod.Code NOT IN (5,7,8),1,0)
I want to run a SELECT in the form:
SELECT CustomerNumber, RuleName, Rule as Value
FROM CustomerRules cr
JOIN CustomerData cd
ON cd.CustomerNumber = cd.CustomerNumber
JOIN ItemsData id
ON cd.ItemID = id.ItemID
JOIN CodesData cod
ON cd.Code = cod.Code
WHERE cr.RuleName = 'ShippingCharged'
To return The Customer Number, the name of the Rule used and the calculated value of the IIF statement. I am getting the text of the Rule calculation, rather than the calculated value.
I've tried various forms of DSQL and TSQL but can't seem to get the column to be treated as a function, just a text value from the table.
Any ideas?
I need to execute stored procedure sp_spaceused for all the tables in my database.
I have used cursor for this, please find the below query.The thing is I need to generate report in a single result set.
For the below query I'm getting different results.
Declare #Name Varchar(500)
Declare #GetName Cursor
Set #Getname = Cursor for
select name from sys.tables
Open #Getname
Fetch Next From #Getname into #Name
While ##Fetch_Status=0
Begin
exec sp_spaceused #Name
Fetch Next From #Getname into #Name
End
Close #GetName
Deallocate #GetName
You can use something like the below (the data types may well need tweaking).
Edit: Please see Joe's answer for the correct data types to use!
create table #t
(
name sysname,
rows bigint,
reserved varchar(50),
data varchar(50),
index_size varchar(50),
unused varchar(50)
)
EXEC sp_MSForEachtable 'insert into #t EXEC sp_spaceused ''?'''
select name,rows,reserved,data,index_size,unused
from #t
create table #Temp (
name nvarchar(128),
[rows] char(11),
reserved varchar(18),
data varchar(18),
index_size varchar(18),
unused varchar(18)
)
insert into #Temp
exec sp_msforeachtable 'sp_spaceused [?]'
select * from #Temp
A faster, set-based solution to this problem is to join sys.dm_db_partition_stats and sys.internal_tables, just like sp_spaceused does. The code below is what runs when you generate the "Disk Usage By Table" report in Management Studio.
In my database, the set-based solution returned in 60 ms, while the cursor ran for 22 seconds.
begin try
SELECT
(row_number() over(order by a3.name, a2.name))%2 as l1,
a3.name AS [schemaname],
a2.name AS [tablename],
a1.rows as row_count,
(a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved,
a1.data * 8 AS data,
(CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
(CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused
FROM
(SELECT
ps.object_id,
SUM (
CASE
WHEN (ps.index_id < 2) THEN row_count
ELSE 0
END
) AS [rows],
SUM (ps.reserved_page_count) AS reserved,
SUM (
CASE
WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
END
) AS data,
SUM (ps.used_page_count) AS used
FROM sys.dm_db_partition_stats ps
GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN
(SELECT
it.parent_id,
SUM(ps.reserved_page_count) AS reserved,
SUM(ps.used_page_count) AS used
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
WHERE it.internal_type IN (202,204)
GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2 ON ( a1.object_id = a2.object_id )
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
ORDER BY a3.name, a2.name
end try
begin catch
select
-100 as l1
, 1 as schemaname
, ERROR_NUMBER() as tablename
, ERROR_SEVERITY() as row_count
, ERROR_STATE() as reserved
, ERROR_MESSAGE() as data
, 1 as index_size
, 1 as unused
end catch
Try this:
Create a table (temp or otherwise) that mirrors the result set of the sproc. Then, in the body of your cursor, run this
INSERT INTO <tablename> EXEC sp_spaceused
after you close/deallocate the cursor, select from the table.