I have an error in syntax # in my code in postgreSQL database, but I don't know what could be wrong. Did I implemented the SQL loop code in rigth way? My SQL code:
DECLARE #Counter INT
SET #Counter=1
WHILE ( #Counter <= 1000)
BEGIN
INSERT INTO punkty (geog) SELECT ST_GeometryN(st_asText(ST_GeneratePoints(geom,1000)), #Counter) FROM panstwo
SET #Counter = #Counter + 1
END
First your code looks like T-SQL(Microsoft and Sybase dialect) and it won't work on PostgreSQL by design
Second loop is not required:
INSERT INTO punkty (geog)
SELECT ST_GeometryN(st_asText(ST_GeneratePoints(geom,1000)), s.Counter)
FROM panstwo
CROSS JOIN generate_series(1,1000) s(counter);
Related
Similar questions have already appeard here, but it seems like I'm doing the same as in other instructions, but it doesn't work. So I have
Declare #Counter Int
Set #Counter = 1
while #Counter <= 1000
Begin
insert into Kiso_task_table ([Numbers],[Square_root])
values ( #Counter, Sqrt(#Counter));
Set #Counter = #Counter + 1;
CONTINUE;
End
SELECT TOP (1000) [Numbers],[Square_root]
FROM [Kiso_task].[dbo].[Kiso_task_table]
and it should give me Numbers from 1 to 1000 and their square roots, respectively - instead it produces "1" all the times? Do you know what is wrong?
Your error is in the type of variable to convert the square root, it must be of the 'float' type
CREATE TABLE #Kiso_task_table
(
[Numbers] INT,
[Square_root] FLOAT,
);
GO
DECLARE #Counter INT
SET #Counter = 1
WHILE #Counter <= 1000
BEGIN
INSERT INTO #Kiso_task_table ([Numbers],[Square_root]) VALUES ( #Counter, Sqrt(#Counter));
SET #Counter = #Counter + 1
CONTINUE
END
SELECT TOP (1000) [Numbers],[Square_root]
FROM #Kiso_task_table
SQRT (Transact-SQL)
Your approach is procedural thinking. Try to start thinking set-based. That means: No CURSOR, no WHILE, no loopings, no do this and then this and finally this. Let the engine know, what you want to get back and let the engine decide how to do this.
DECLARE #mockupTarget TABLE(Number INT, Square_root DECIMAL(12,8));
WITH TallyOnTheFly(Number) AS
(
SELECT TOP 1000 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values
)
INSERT INTO #mockupTarget(Number,Square_root)
SELECT Number,SQRT(Number)
FROM TallyOnTheFly;
SELECT * FROM #mockupTarget ORDER BY Number;
The tally-cte will create a volatile set of 1000 numbers. This is inserted in one single statement.
Btw
I tested your code against my mockup table and it was working just fine...
I need a loop in SQL Server 2008 like below:
while #counter < (Select Count(Id) from #Requests)
begin
exec ApplyData(Select TOP 1 Id
from (select TOP #counter Id from #Requests) T
order by Id Desc
)
set #counter = #counter + 1
end
It says the usage of #counter inside the Select query is wrong (syntax error). What is the correct way to use it? How can I fix the syntax error?
Thanks
Use like this
select TOP(#counter)
I have this query..
Begin
declare #Col int,
#lev int,
#Plan int
select #Col = 411
select #lev = 16
select #Plan = 780
--Insert into baCodeLibrary(Plan_Num,Level_Num,Column_Num,Block_Num,Code_Id,Sort_Order,isactive,Added_By,DateTime_Added,Updated_By,DateTime_Updated)
Select Distinct
#plan,
#lev,
#col,
ba_Object_Id - 5539,
ba_Object_Id,
ba_OBject_Desc,
ba_Object_Id - 5539,
1,
'xyz',
GETDATE(),
'xyz',
GETDATE()
from baObject
where ba_OBject_Id > 5539
and ba_Object_Id < 5554
end
Here I have only for the #col = 411, but I want to loop for all the column until 489
Could any body help me out how to write the loop in this query to select all the columns from 411 to 489?
Thanks in advance
How about not thinking about this in terms of a loop, and instead think about it in terms of a set?
declare #lev int,
#Plan int;
select #lev = 16,
#Plan = 780;
;WITH n(n) AS
(
SELECT TOP (489-411) Number
FROM master.dbo.spt_values
WHERE type = N'P' ORDER BY Number
)
--Insert dbo.baCodeLibrary(...)
SELECT DISTINCT
#plan,
#lev,
n.n,
ba.ba_Object_Id - 5539,
ba.ba_Object_Id,
ba.ba_Object_Desc,
ba.ba_Object_Id - 5539,
1,
'xyz',
GETDATE(),
'xyz',
GETDATE()
FROM dbo.baObject AS ba CROSS JOIN n
where ba.ba_Object_Id > 5539
and ba.ba_Object_Id < 5554;
There's no actual looping mechanism in your query as it exists now. You'll need to implement something like a while loop in order to get that functionality.
See: http://technet.microsoft.com/en-us/library/ms178642.aspx
It'll look something like
DECLARE #counter int
SET #counter = 1
WHILE #counter < 10
BEGIN
-- loop logic
SET #counter = #counter + 1
END
Looping can be performed three ways in T-SQL; a WHILE loop, a SET based operation, or a CURSOR.
T-SQL / SQL Server are optimised for SET based operations, and they are easily the most efficient way to loop, but it all depends on what you're trying to achieve.
You may be warned away from cursors, with good reason, but they are perfectly acceptable as long as you understand what you're doing. Here's an example of a very simple, fast cursor:
DECLARE #myColumn VARCHAR(100)
DECLARE cTmp CURSOR FAST_FORWARD FOR
SELECT MyColumn
FROM MyTable (nolock)
OPEN cTmp
FETCH NEXT FROM cTmp INTO #myColumn
WHILE ##FETCH_STATUS = 0
BEGIN
-- Do something with #myColumn here
FETCH NEXT FROM cTmp INTO #myColumn
END
CLOSE cTmp
DEALLOCATE cTmp
GO
Please do not use this code without reading up on cursors first - they should only be used when SET based operations are not suitable. It depends entirely on what you're trying to achieve - cursors can be very resource hungry, and can result in locked records / tables if you're not careful with the hints you apply to them.
I need to use a select expression in a while loop and I use the below sample code:
declare #i integer
set #i=1
while (#i<10)
begin
select #i as m;
set #i=#i+1
END
this code returns 10 separate table! I want it to return all select results in one table... is that possible? if yes... how?
You can use a temp table or table variable for this.
Here's how to do it using a temp table.
CREATE TABLE #t (m INT)
DECLARE #i INT
SET #i=1
WHILE (#i<10)
BEGIN
INSERT INTO #t SELECT #i
SET #i=#i+1
END
SELECT m FROM #t
Very similar with a table variable
DECLARE #t TABLE (m INT)
DECLARE #i INT
SET #i=1
WHILE (#i<10)
BEGIN
INSERT INTO #t SELECT #i
SET #i=#i+1
END
SELECT m FROM #t
It is not possible. Each SELECT statement generates its own result set. You can use temp table to add results of each iteration and then get all in one table. To generate sequence of integers you can use this (for SQL SERVER 2005 + )
;WITH CTE
AS
(
SELECT 1 N
UNION ALL
SELECT N + 1 FROM CTE
WHERE N<10
)
SELECT N FROM CTE
squillman got it...with #t (create table # - table persisted at top-level scope while session is open - if you have several batch statements, you can reference this table in any after declaration until you drop the table)
Cris also got it with #test (declare # table - variable - only persisted in the current scope - single execution batch block...note that there are several performance issues that can be introduced if you use this)
the last type of temp table you can use is a global temp table (create table ## - lasts as long as the session that created it stays open or until it is dropped)
with #t, you may want to add this to the beginning of your script if you don't close the session:
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
Enjoy the temp tables!
declare #i integer
DECLARE #test TABLE(
m /*your data type*/
)
set #i=1
while (#i<10)
begin
insert into #test select #i;
set #i=#i+1
END
select * from #test
I found this function which returns three rows for the following query:
select * from dbo.split('1 2 3',' ')
However, I need to use values from a field instead of '1 2 3'.
I tried:
select * from dbo.split(select top 1 myfield from mytable,' ')
But it fails saying incorrect syntax.
It doesn't have to use the function above, so feel free to recommend another function or different way to go about it. To clarify, I only need to parse the values from a single row of a single field.
You need to apply the split(myfield) function to each row in mytable. When the split function is a table valued function the correct answer is the APPLY operator:
The APPLY operator allows you to
invoke a table-valued function for
each row returned by an outer table
expression of a query.
So the answer must be:
select *
from mytable
cross apply dbo.split(myfield, ' ');
Example:
create table mytable (myfield varchar(10));
insert into mytable (myfield) values ('1 2 3');
go
create function split (#list varchar(max), #delimiter char(1))
returns #shards table (value varchar(8000))
with schemabinding
as
begin
declare #i int;
set #i = 0;
while #i <= len(#list)
begin
declare #n int;
set #n = charindex(#delimiter, #list, #i);
if 0 = #n
begin
set #n = len(#list);
end
insert into #shards (value)
values (substring(#list, #i, #n-#i+1));
set #i = #n+1;
end
return;
end
go
select *
from mytable
cross apply dbo.split(myfield, ' ');
Have you tried
SELECT dbo.split(myfield, ' ') AS x FROM mytable
EXEC SP_DBCMPTLEVEL 'YOUR_DB_NAME',90;
Should fix the problem of Remus's incompatible code. I just looked into my own db and it was set to level '80' which means it supports <= SQL 2000. After applying the procedure above, the code runs and works perfectly.
Now I just need to find out wtf relies on SQL2000 and breaks in SQL2005...AHH!
This MSDN link will help you determine whether your fn/usp/app layers will be negatively impacted: http://msdn.microsoft.com/en-us/library/bb510680.aspx
Try
select * from dbo.split((select top 1 myfield from mytable),' ')
put the UDF around your column, example
SELECT dbo.split(myfield, ' ') as SplitValue
FROM mytable