sql server 2000 stored procedure - stored-procedures

I have created a store procedure for updating the patient name in multiple tables. When I execute it, shows the error like
Server: Msg 170, Level 15, State 1,
Line 1 Line 1: Incorrect syntax near
'='.
This is my code. How to recover it? Please help me
create procedure uppatname #pid varchar(150),#pname varchar(150)
as begin
declare #i as integer
declare #i1 as integer
declare #ttnm as varchar(100)
declare #tblnam as varchar(100)
drop table tbname
SELECT IDENTITY(int, 1,1) AS RowNumber, table_name
INTO tbname
FROM information_schema.columns
WHERE column_name = 'pid'
AND table_catalog = 'hospital'
AND table_name NOT LIKE 'T%'
SET #i = (select count(*) from information_schema.columns
where column_name='pid' and table_catalog='hospital'
and table_name not like 'T%')
SET #i1 = 1
WHILE #i1 <= #i
BEGIN
SET #tblnam = (select table_name from tbname where rownumber = #i1)
SET #ttnm = ('select * from ' + #tblnam + 'where pid = ' + #pid)
EXEC (#ttnm)
SET #i1 = #i1 + 1
END
END

What is the need for this task? Instead of storing denormalised redundant copies of the same name that you then have to manually keep up-to-date can't you store it in one place then join on it?
Some random comments about the code.
Why are you dropping and recreating the table tbname each time instead of just using truncate?
Although why are you using a permanent table for this at all? If you have concurrent executions of the stored procedure you could end up updating the wrong patient record with the wrong name. You could just use a #temp table or a #table variable
You don't need to do the SELECT COUNT(*)... and run the query again get the rowcount. You can just do ##rowcount
You should use quote_name around the table name and schema qualify it. As pid is not numeric it would need to be quoted in the query though actually you should use sp_executesql to allow you to parameterise pid
CREATE PROCEDURE uppatname #pid VARCHAR(150),
#pname VARCHAR(150)
AS
BEGIN
DECLARE #i AS INTEGER
DECLARE #i1 AS INTEGER
DECLARE #dyn_sql AS NVARCHAR(4000)
DECLARE #tblnam AS SYSNAME
DECLARE #schema_name SYSNAME
DECLARE #tbname TABLE (
RowNumber INT IDENTITY(1, 1) PRIMARY KEY,
schema_name SYSNAME,
table_name SYSNAME )
INSERT INTO #tbname
SELECT TABLE_SCHEMA,
TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'pid'
AND TABLE_CATALOG = 'hospital'
AND TABLE_NAME NOT LIKE 'T%'
SET #i = ##ROWCOUNT
SET #i1 = 1
WHILE #i1 <= #i
BEGIN
SELECT #tblnam = table_name,
#schema_name = schema_name
FROM #tbname
WHERE RowNumber = #i1
SET #dyn_sql = N'SELECT *
FROM ' + QUOTENAME(#schema_name) + '.'
+ QUOTENAME(#tblnam) + '
WHERE pid = #pid';
EXEC sp_executesql
#dyn_sql,
N'#pid VARCHAR(150)',
#pid=#pid
SET #i1 = #i1 + 1
END
END
NB: You could also concatenate the whole script in a single query and execute it but that technique isn't 100% guaranteed so I haven't used it above.

Related

Error -206 creating Interbase stored procedure

I am attempting to create a stored procedure using an IBConsole interactive SQL window. The intent of the procedure is to gather data from two tables, do some processing on that data, insert rows containing that data into a working table, then return the rows from the working table as the stored procedure result. The stored procedure:
SET TERM ^;
CREATE PROCEDURE BIBLIO_SUBJECT
RETURNS (ID INTEGER, SUBJECT VARCHAR(200))
AS
DECLARE VARIABLE CUR_SUBJECT VARCHAR(200);
DECLARE VARIABLE SUBJECT_LIST VARCHAR(500);
DECLARE VARIABLE BIBLIOID INTEGER;
DECLARE VARIABLE NEXTPOS INTEGER;
BEGIN
DELETE FROM TSUBJECTS;
FOR SELECT BIBLIO.ID, BIBLIO.SUBJECTS
FROM BIBLIO
WHERE BIBLIO.PUBLISH = TRUE
INTO :BIBLIOID, :SUBJECT_LIST
DO
BEGIN
SUBJECT_LIST = BIBLIO.SUBJECTS + ';';
NEXTPOS = LOCATE(";", SUBJECT_LIST);
WHILE (:NEXTPOS > 1) DO
BEGIN
CUR_SUBJECT = SUBSTR(:SUBJECT_LIST, 1, NEXTPOS - 1);
SUBJECT_LIST = SUBSTR(:SUBJECT_LIST, NEXTPOS + 1, STRLEN(SUBJECT_LIST));
INSERT INTO TSUBJECTS (SUBJECT, ID) VALUES(:CUR_SUBJECT, :BIBLIOID);
NEXTPOS = LOCATE(";", SUBJECT_LIST);
END
END
FOR SELECT BIBLIO_BEAST.BIBLIO_ID, BEAST.BEAST_NAME
FROM BIBLIO_BEAST
INNER JOIN BEAST ON (BEAST.ID = BIBLIO_BEAST.BEAST_ID)
INNER JOIN BIBLIO ON (BIBLIO.ID = BIBLIO_BEAST.BIBLIO_ID)
WHERE BIBLIO.PUBLISH = TRUE
INTO :BIBLIOID, :CUR_SUBJECT
DO
BEGIN
INSERT INTO TSUBJECTS (SUBJECT, ID) VALUES(:CUR_SUBJECT, :BIBLIOID);
END
FOR SELECT ID, SUBJECT
FROM TSUBJECTS
INTO :ID, :SUBJECT
DO
SUSPEND;
END^
SET TERM ;^
When I execute the above code in IBConsole I get the error:
Error at line 2
Dynamic SQL Error
SQL error code = -206
Column unknown
SQL - CREATE PROCEDURE BIBLIO_SUBJECT
RETURNS (ID INTEGER, SUBJECT VARCHAR(200))
AS
DECLARE VARIABLE CUR_SUBJECT VARCHAR(200);
DECLARE VARIABLE SUBJECT_LIST VARCHAR(500);
DECLARE VARIABLE BIBLIOID INTEGER;
DECLARE VARIABLE NEXTPOS INTEGER;
BEGIN
DELETE FROM TSUBJECTS;
FOR SELECT BIBLIO.ID, BIBLIO.SUBJECTS
FROM BIBLIO
WHERE BIBLIO.PUBLISH = TRUE
INTO :BIBLIOID, :SUBJECT_LIST
DO
BEGIN
SUBJECT_LIST = BIBLIO.SUBJECTS + ';';
NEXTPOS = LOCATE(";", SUBJECT_LIST);
WHILE (:NEXTPOS > 1) DO
BEGIN
CUR_SUBJECT = SUBSTR(:SUBJECT_LIST, 1, NEXTPOS - 1);
SUBJECT_LIST = SUBSTR(:SUBJECT_LIST, NEXTPOS + 1, STRLEN(SUBJECT_LIST));
INSERT INTO TSUBJECTS (SUBJECT, ID) VALUES(:CUR_SUBJECT, :BIBLIOID);
NEXTPOS = LOCATE(";", SUBJECT_LIST);
END
END
FOR SELECT BIBLIO_BEAST.BIBLIO_ID, BEAST.BEAST_NAME
FROM BIBLIO_BEAST
INNER JOIN BEAST ON (BEAST.ID = BIBLIO_BEAST.BEAST_ID)
INNER JOIN BIBLIO ON (BIBLIO.ID = BIBLIO_BEAST.BIBLIO_ID)
WHERE BIBLIO.PUBLISH = TRUE
INTO :BIBLIOID, :CUR_SUBJECT
DO
BEGIN
INSERT INTO TSUBJECTS (SUBJECT, ID) VALUES(:CUR_SUBJECT, :BIBLIOID);
END
FOR SELECT ID, SUBJECT
FROM TSUBJECTS
INTO :ID, :SUBJECT
DO
SUSPEND;
END
It doesn't say which column is "unknown", and line 2 is (apparently) the RETURNS clause of the CREATE PROCEDURE. Not at all helpful.
Each of the SQL statements in the stored procedure (3 SELECTs, a DELETE, 2 INSERTs) work without error if executed separately in an Interactive SQL window, so all of their columns are "known". BIBLIO_SUBJECT is not the name of an existing stored procedure, nor is it the name of an existing table, or anything else in the database.
This has me baffled. Online searches provide no answer. So I am hoping the clever Stack Overflow people can help me get this working.
David
Well, I figured it out. It was the statement:
SUBJECT_LIST = BIBLIO.SUBJECTS + ';';
The SUBJECT_LIST variable is already used in the preceding select. A silly mistake, but I am old.
Not that it matters since the Interbase UDF functions Locate() and Substr() can only handle 80 character strings, which makes them really useless to me... and probably useless to most.

Dynamic Creation of External Tables in Synapse

I have a json string which is the result of Get Metadata activity in data factory in the following format: {"structure": [{"name": "Id","type": "String"},{"name": "IsDeleted","type": "Boolean"},{"name": "RowVersion","type": "Byte[]"}, {"name": "ModelId","type": "String"}]
This json is showing the schema of parquet file. I pass this json along with the parquet filename and uctnow() to a stored procedure to create a table of schema for that file with the following code
CREATE OR ALTER PROCEDURE [CreateExternalTables] (
#schema NVARCHAR (MAX), #tableName NVARCHAR(MAX), #ExecTime NVARCHAR(MAX)
) AS
BEGIN
IF OBJECT_ID('tempdb..#tables_to_create', 'U') IS NOT NULL
DROP TABLE #tables_to_create
CREATE TABLE #tables_to_create (
tableName NVARCHAR (MAX),
fieldOrder NVARCHAR (MAX),
fieldName NVARCHAR (MAX),
fieldType NVARCHAR (MAX),
translatedType NVARCHAR (MAX),
executeTime NVARCHAR (MAX)
)
BEGIN
WITH Fields (fieldOrder, fieldName, fieldType) AS (
SELECT
[key] AS fieldOrder,
JSON_VALUE([value], '$.name') AS fieldName,
JSON_VALUE([value], '$.type') AS fieldType
FROM
OPENJSON(#schema)
)
INSERT INTO
#tables_to_create(
tableName,
fieldOrder,
fieldName,
fieldType,
translatedType,
executeTime
)
SELECT
#tableName,
fieldOrder,
fieldName,
fieldType,
CASE
WHEN fieldType = 'Single' THEN 'real'
WHEN fieldType = 'Boolean' THEN 'bit'
WHEN fieldType = 'Double' THEN 'float'
WHEN fieldType = 'Int64' THEN 'bigint'
ELSE NULL
END AS translatedType,
#ExecTime
FROM
Fields
END
END;
The overall setup is like below:
But I receive the following error which I'm not sure why:
What I would like to do is to create this temo table in stored procedure in order to create external tables in a automatic way.
To be precise I'm following this link to do it:
create-external-dataset
Any help is highly appreciated.
UPDATE
After solving the first problem with #wBob 's help I follow the rest of the link to create the external tables with the following which I inserted into my stored procedure:
FROM
Fields
END
Declare #sqlCommand nvarchar(max);
Declare #folderPath nvarchar(max);
SET
#sqlCommand = 'IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + #tableName + ']'') AND type in (N''U''))
CREATE EXTERNAL TABLE [dbo].[' + #tableName + '] ('
WHILE((SELECT COUNT(*) FROM #tables_to_create) > 0)
BEGIN
DECLARE #key int
SELECT
#key = MIN(fieldOrder)
FROM
#tables_to_create
WHERE
executeTime = #ExecTime
DECLARE #fieldName VARCHAR(50)
DECLARE #translatedType VARCHAR(50)
SELECT
#fieldName = fieldName,
#translatedType = translatedType
FROM
#tables_to_create
WHERE
fieldOrder = #key
AND executeTime = #ExecTime
SET
#sqlCommand = #sqlCommand + '
[' + #fieldName + '] [' + #translatedType + '] NULL'
DELETE FROM
#tables_to_create
WHERE
fieldOrder = #key
AND executeTime = #ExecTime
IF((SELECT COUNT(*) FROM #tables_to_create WHERE executeTime = #ExecTime) > 0)
SET
#sqlCommand = #sqlCommand + ', '
END
SET
#sqlCommand = #sqlCommand + '
)
WITH
(
LOCATION = ''/' + /main/json/ + ''',
DATA_SOURCE = DataLakeStaged,
FILE_FORMAT = StagedParquet
)'
EXEC(#sqlCommand)
END;
However I receive the following error:
As per the error message, queries are not supported in the conditions of WHILE statement in Azure Synapse Analytics. Dedicated SQL pools are MPP systems that have some slight differences from box-product SQL Server and Azure SQL DB and more generally, loops are a pattern that don't translate that well. You should consider creating a stored procedure that does not loop and leave any looping required to the For Each activity in Azure Data Factory (ADF) / Synapse Pipelines which can loop in parallel.
If you do require a loop, there are multiple examples of doing loops in dedicated SQL pools online, but there is a good example in the official documentation, reproduced here in the event the link moves:
-- First, create a temporary table containing a unique row number used to identify the individual statements:
CREATE TABLE #tbl
WITH
( DISTRIBUTION = ROUND_ROBIN
)
AS
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Sequence
, [name]
, 'UPDATE STATISTICS '+QUOTENAME([name]) AS sql_code
FROM sys.tables
;
-- Second, initialize the variables required to perform the loop:
DECLARE #nbr_statements INT = (SELECT COUNT(*) FROM #tbl)
, #i INT = 1
;
-- Now loop over statements executing them one at a time:
WHILE #i <= #nbr_statements
BEGIN
DECLARE #sql_code NVARCHAR(4000) = (SELECT sql_code FROM #tbl WHERE Sequence = #i);
EXEC sp_executesql #sql_code;
SET #i +=1;
END

Procedure runs,but doesn't do anything

I have a little problem with running a certain procedure in MariaDB.
The funny thing is that when i run the procedure,it doesn't show any errors,but unfortunately it doesn't do anything.
And I can't simply find what's wrong.
Guys please help.Thx
Query:
CREATE DEFINER=`root`#`127.0.0.1` PROCEDURE `p_tun_removal`(IN `GeoTerID` INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
DECLARE #done INT DEFAULT FALSE;
DECLARE #CurrentVersion INT;
DECLARE #CorrectVersion INT;
DECLARE #BeginVersion INT;
DECLARE cur1
CURSOR FOR
SELECT Distinct(Version)
FROM geo_patch
WHERE TerID = GeoTerID AND Version >= BeginVersion;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
declare exit handler for sqlexception
begin
rollback;
resignal;
end;
CREATE Temporary TABLE `tunnel_temp` (
`ID` INT NOT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
insert into tunnel_temp ( ID ) (
SELECT ID from geo_patch
WHERE Version in ( select Version from geo_patch where Substance = 0 ) and TerID = GeoTerID
);
SET #BeginVersion = ( SELECT Version from geo_patch where ID = ( SELECT ID from tunnel_temp limit 1 ) ) - 1 ;
SET #CorrectVersion = #BeginVersion;
IF (#CorrectVersion < 2) THEN
SET #CorrectVersion = 2;
END IF;
START TRANSACTION;
DELETE FROM geo_patch where ID in ( Select ID from tunnel_temp );
open cur1;
version_loop: LOOP
FETCH cur1 into #CurrentVersion;
IF done THEN
LEAVE version_loop;
END IF;
UPDATE geo_patch SET Version = #CorrectVersion WHERE Version = #CurrentVersion;
SET CorrectVersion = CorrectVersion + 1;
END LOOP;
close cur1;
COMMIT;
UPDATE terrain_blocks SET GeoVersion = ( select Version from geo_patch where TerID = GeoTerID order by Version desc limit 1 ) WHERE ID = GeoTerID;
drop temporary table if exists tunnel_temp;
END
Don't use the construct IN ( SELECT ... ), use a JOIN instead.
Try to avoid cursors by doing the entire operation in a single statement.

function or stored procedure for bulk insert in table by sets

how can i convert the following to teradata stored procedure or some function :
WHILE EXISTS (SELECT * FROM #temp_set1)
BEGIN
/*group of statemnts :delete insert etc
like */
INSERT INTO #temp_set
SELECT TOP 200 * FROM #temp_set1;
INSERT INTO Activepull
as select * from #temp_set1
and this should occur for each set of 200 untill all inserts
end;
There are more than 60000 rows in #temp_set1 so want to insert by sets.
Thanks.
Written on my phone, but I would use the over expression. It creates a kind of pseudo Identity column that you can then use to paginate. And you can even choose the order based on an order by clause.
Declare #IntervalSize int = 100
Declare #BeginSet int = 0,
#EndSet int = #IntervalSize
While #Counter < (Select Max(ROW_NUMBER() OVER (ORDER BY someColumn desc) From #temp_set1)
Begin
Insert Into #temp_set
Select *, Row_Number() Over (Order By someColumn desc) As MyIdentity
Where MyIdentity Between #BeginSet And #EndSet
Select #BeginSet = #BeginSet + #IntervalSize,
#EndSet = #EndSet + #IntervalSize
End

Trying to write an UPDATE comm in a Stored Procedure with Dynamic SQL

Here goes, second post, first didn't go to well....
I am calling an SP from a Gridview in ASP. I pass in a table name as a variable along with some other variables. I need to UPDATE my original table that the Gridview attaches to but also build a Datalist, I have used a Fetch and got it working fine. Cycle through those records and INSERT data into third table. I was told (in first post) I need to build the SQL string first then execute it. when I write it that way the second part of the insert does not work.
Here is the code in its sliced up form because of efforts to find a succesfull structure....
#currTable varchar(100),
#ID int,
#short_Text varchar(250),
#brief_Descrip varchar(250) = Null,
#needsTranslation varchar(10) = Null,
#prev_LangString varchar(250) = Null,
#lang_String varchar(250) = Null,
#original_lang_String varchar(250) = Null,
#StringID_from_Master varchar(250),
#GUID varchar(250) = Null
/*
*/
AS
SET NOCOUNT ON;
DECLARE #userTable AS VARCHAR(200);
SET #userTable = #currTable
DECLARE #submitDate1 DATETIME;
SET #submitDate1 = GETDATE()
SET #prev_LangString = #original_lang_String
SET #needsTranslation = 'false'
DECLARE #sql varchar(max)
-- Establish update to the language tabel of user and prepare to search DB for all strings that will need to be updated.
BEGIN
-- DECLARE #sql nvarchar(4000)
SELECT #sql = ' UPDATE ' + #currTable +
' SET [lang_String] = ' + #lang_String +
' WHERE (ID = ' + #ID + ' ';
EXEC sp_executesql #sql, N'#ID nvarchar(10)', #ID
-- UPDATE #userTable
-- SET [lang_String] = #lang_String, [date_Changed] = #submitDate1, [prev_LangString] = #prev_LangString, [needsTranslation] = #needsTranslation, [brief_Descrip] = #brief_Descrip
-- WHERE (ID = #ID)
END
BEGIN
DECLARE usedIN_DBScursor CURSOR
FOR
SELECT tblUniquetblStringsMaster_ID, Database_Name, dbKeyID_ofStringName
FROM tblDBUsage
WHERE (tblUniquetblStringsMaster_ID = #StringID_from_Master );
-- Declare the variables to store the values returned by FETCH.
DECLARE #tblUniquetblStringsMaster_ID AS INT;
DECLARE #dbKEYID as INT;
DECLARE #dbName as varchar(100);
OPEN usedIN_DBScursor;
-- Perform the first fetch and store the values in variables.
-- Note: The variables are in the same order as the columns
-- in the SELECT statement.
FETCH NEXT FROM usedIN_DBScursor
INTO #tblUniquetblStringsMaster_ID, #dbName, #dbKEYID;
-- Check ##FETCH_STATUS to see if there are any more rows to fetch.
WHILE ##FETCH_STATUS = 0
BEGIN
-- Update pending strings table with translation.
BEGIN
INSERT INTO tblPendingDBUpdates
(stringMasterID, databaseName, databaseStringID, englishText, foreignLangText, submitDate, GUID)
VALUES (#StringID_from_Master, #dbName, #dbKEYID, #short_Text, #lang_String, #submitDate1, #GUID);
END
-- SET #sql = ''
-- This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM usedIN_DBScursor
INTO #tblUniquetblStringsMaster_ID, #dbName, #dbKEYID;
END
CLOSE usedIN_DBScursor;
DEALLOCATE usedIN_DBScursor;
END
RETURN
It seems that your procedure could be re-written as follows:
ALTER PROCEDURE dbo.procedure_name
#currTable varchar(100),
#ID int,
#short_Text varchar(250),
#brief_Descrip varchar(250) = Null,
#needsTranslation varchar(10) = Null,
#prev_LangString varchar(250) = Null,
#lang_String varchar(250) = Null,
#original_lang_String varchar(250) = Null,
#StringID_from_Master varchar(250),
#GUID varchar(250) = Null
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SELECT #sql = N' UPDATE ' + QUOTENAME(#currTable) + ' SET [lang_String] = '''
+ REPLACE(#lang_String,'''','''''') + ''' WHERE ID = ' + RTRIM(#ID) + ';';
EXEC sp_executesql #sql;
INSERT tblPendingDBUpdates
(
stringMasterID,
databaseName,
databaseStringID,
englishText,
foreignLangText,
submitDate,
[GUID]
)
SELECT
#StringID_from_Master,
Database_Name,
dbKeyID_ofStringName,
#short_Text,
#lang_String,
#submitDate1,
#GUID
FROM
tblDBUsage
WHERE tblUniquetblStringsMaster_ID = #StringID_from_Master;
END
GO
However, I am not sure why you need a cursor in your original version, or what you mean by "does not work." Can you explain?
I don't quite understand your problem, but I see one thing that's obviously wrong: In the SQL you're building a string literal is missing its quotes and there's a missing parenthesis. The SQL you're generating would look like this:
UPDATE table_name SET [lang_String] = lang_string WHERE (ID = 123
So it should be:
DECLARE #sql nvarchar(4000)
SELECT #sql = 'UPDATE ' + #currTable + ' SET [lang_String] = ''' + #lang_String + ''' WHERE ID = ' + #ID
Which generates this SQL:
UPDATE table_name SET [lang_String] = 'lang_string' WHERE ID = 123

Resources