Can I create a table with columns named similar to field value of another table, return by SELECT statement - sql

Question Image
When I execute this script, there is a syntax error. What is wrong with this?
use TEST
go
CREATE TABLE newTagsTable
(
(SELECT TEST.dbo.dynamicTags.Alais
FROM TEST.dbo.dynamicTags
WHERE ID = 2) varchar(200)
);

Is this what you need ?
SELECT Alais
into newTagsTable
FROM dynamicTags
WHERE ID = 2;
DEMO
Ok, so something like this then:
create procedure test_proc
as
declare #p_sql varchar(2000);
declare #p_sql_2 varchar(2000);
declare #getid CURSOR;
SET #getid = CURSOR FOR
SELECT Alais
FROM dynamicTags;
begin
set #p_sql = 'create table newTagsTable (';
OPEN #getid
FETCH NEXT
FROM #getid INTO #p_sql_2
WHILE ##FETCH_STATUS = 0
begin
set #p_sql = #p_sql + #p_sql_2 + ' varchar(20),'
FETCH NEXT FROM #getid INTO #p_sql_2
end;
set #p_sql = left(#p_sql, len(#p_sql)-1) + ')';
EXEC (#p_sql);
end;
And then just execute the procedure:
exec test_proc
You can add parameters to this to make it more usable for orher situations...
Here is the demo for this second option:
DEMO

Related

reverse where query in mysql2

I want to find records using like query but in reverse mode
For exa: I have one string ts5e434
And now in databse I have one column called geohash and its contan comma seperated values
1) "ts5e4,ts5,ts5e434"
2) "ab,ye"
3) "ts,thh"
4) "t"
So here I want to get 1, 3 and 4 no records because its partially matching string
exa like clause
SELECT
*
FROM
service_geohashes
WHERE
'ts5e434' LIKE geohashes
Can anyone help me
Thanks in advance
I created function "LikeAny" in MSSQL which looks like:
CREATE FUNCTION [dbo].[LikeAny](#text nvarchar(MAX), #delimiter varchar(20), #comparestring nvarchar(MAX))
RETURNS BIT AS
BEGIN
DECLARE #LikeAny BIT = 0,
#TempString nvarchar(MAX)
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT value FROM STRING_SPLIT(#text, #delimiter)
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO #TempString
WHILE ##FETCH_STATUS = 0
BEGIN
--Do something with Id here
IF (#TempString <> '' AND #comparestring LIKE N'%' + #TempString + '%')
BEGIN
SET #LikeAny = 1
BREAK;
END
ELSE
FETCH NEXT FROM MY_CURSOR INTO #TempString
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
RETURN #LikeAny
END
If you use this in your example, it should look like:
SELECT
*
FROM
service_geohashes
WHERE
[dbo].[LikeAny](geohashes ,',', 'ts5e434') = 1
I tried also to convert the function above into MySQL but I had no option to test it on real environment
it looks like:
DROP FUNCTION IF EXISTS LikeAnyCommaDelimited;
DELIMITER $$
CREATE FUNCTION LikeAnyCommaDelimited(p_text longtext, p_comparestring longtext)
RETURNS TINYINT
DETERMINISTIC
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_LikeAny TINYINT DEFAULT 0;
DECLARE v_TempString longtext;
DECLARE v_SQL longtext;
drop temporary table if exists tempa;
drop temporary table if exists tempb;
CREATE TEMPORARY TABLE tempa( txt text );
CREATE TEMPORARY TABLE tempb( val char(255) );
insert into tempa values(p_text);
set v_SQL = concat("insert into tempb (val) values ('", replace(( select group_concat(distinct txt) as data from tempa), ',', "'),('"),"');");
prepare statement1 from #sql;
execute statement1;
DEClARE split_cursor CURSOR FOR
SELECT value FROM (select distinct(val) as value from tempb);
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN split_cursor;
get_string: LOOP
FETCH split_cursor INTO v_TempString;
IF v_finished = 1 THEN
LEAVE get_string;
END IF;
IF (v_TempString <> '' AND p_comparestring LIKE N'%' + CONCAT(v_TempString , '%') THEN
BEGIN
SET v_LikeAny = 1;
LEAVE get_string;
END
END LOOP get_string;
CLOSE split_cursor;
END$$
DELIMITER ;
Let me know if you have any issues.

SQL Server 2014 - sp_describe_cursor_column for dynamic queries issue

Basically I want to know columns/aliases of result set from dynamic query. I tried to use sp_describe_cursor_column but without success.
It returns me that cursor does not exits. But I can fetch values from such cursor...
The code is :
ALTER PROC TestProc
AS
DECLARE #dynamicSQL nvarchar(200)
-- Have code that will construct the dynamic SQL
SET #dynamicSQL = ' select table_name, TABLE_TYPE from INFORMATION_SCHEMA.TABLES'
-- The cursor that will be filled by the dynamic SQL
DECLARE #outputCursor CURSOR
-- Create the dynamic SQL to fill a CURSOR instead
SET #dynamicSQL = 'SET #outputCursor = CURSOR FORWARD_ONLY STATIC FOR ' +
#dynamicSQL + ' ; OPEN #outputCursor'
-- Execute dynamic sql
exec sp_executesql -- sp_executesql will essentially create a sproc
#dynamicSQL, -- The SQL statement to execute (body of sproc)
N'#outputCursor CURSOR OUTPUT', -- The parameter list for the sproc: OUTPUT CURSOR
#outputCursor OUTPUT -- The parameter to pass to the sproc: the CURSOR
declare #Report cursor
exEC sp_describe_cursor_columns
#cursor_return = #Report OUTPUT
,#cursor_source = N'local'
,#cursor_identity = N'outputCursor';
-- Code that will just output the values from the cursor
DECLARE #tableName nvarchar(200), #table_type nvarchar(200);
FETCH NEXT FROM #outputCursor INTO #tableName, #table_type
-- Loop while there're more things in the cursor
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #tableName
FETCH NEXT FROM #outputCursor INTO #tableName, #table_type
END
-- Be nice, close & deallocate cursor
CLOSE #outputCursor
DEALLOCATE #outputCursor
And this is the result:
Msg 16916, Level 16, State 4, Procedure sp_describe_cursor_columns,
Line 23 A cursor with the name 'outputCursor' does not exist.
DATABASE_UPDATE
SYSTEM_CONFIGURATION ....
I want as result to see table_name , table_type.
Don't tell me that I can just extarct it from string, becasue user may send select * from xxxx.
I found some other way how to extract description of result set for dynamic queries.
declare #Table nvarchar(200) ;
DECLARE #dynamicSQL nvarchar(200)
SET #dynamicSQL = 'select table_name, TABLE_TYPE from INFORMATION_SCHEMA.TABLES'
SELECT #Table = COALESCE(#Table + ', ', '') + Name
FROM sys.dm_exec_describe_first_result_set
(#dynamicSQL, NULL,1)
print #Table

SQL - Add column and set value after IF NOT EXISTS

I'm having trouble with an Alter Table if a column doesn't exist.
This is my code:
DECLARE #appId INT
DECLARE #cursor CURSOR
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'MinMktIdeaParticipants' AND TABLE_NAME = 'mkIdeaCategories')
BEGIN
ALTER TABLE mkIdeaCategories
ADD MinMktIdeaParticipants int NOT NULL DEFAULT 1
END
IF EXISTS(SELECT Value FROM appConfiguration WHERE CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10)
BEGIN
SET #cursor = CURSOR FAST_FORWARD
FOR
SELECT ApplicationId FROM mkMarket
OPEN #cursor
FETCH NEXT FROM #cursor INTO #appId
WHILE (##Fetch_Status >= 0)
BEGIN
UPDATE
mkIdeaCategories
SET MinMktIdeaParticipants = (SELECT Value FROM appConfiguration
WHERE ApplicationId = #appId AND CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10)
WHERE IdeaCatId IN
(select distinct(theme.IdeaCatId) from dbo.mkIdeaCategories theme
inner join dbo.mkMarketIdeaCategories mic ON theme.IdeaCatId = mic.IdeaCatId
inner join mkMarket m on m.MarketId=mic.MarketId
WHERE m.ApplicationId = #appId)
FETCH NEXT FROM #cursor INTO #appId
END
CLOSE #cursor
DEALLOCATE #cursor
DELETE * FROM appConfiguration WHERE CodeId = 16 AND AppConfigurationTypeId = 3 AND ModuleId = 10
END
I don't think there are any errors. For some reason, the output error is
Msg 207, Level 16, State 1, Line 53
Invalid column name 'MinMktIdeaParticipants'.
I've already searched for similar questions, but couldn't find an answer that solved the problem.
When SQL Server processes a script, there are two phases. The first phase is compilation. The second is execution.
The error that you are getting is a compilation error. All the code is compiled, regardless of the if conditions. So, you are getting an error because the column doesn't exist. The column wouldn't be created until the execution phase.
One solution is to change the second part of the code to dynamic SQL, using exec (or better yet exec sp_executesql) to execute the code.
Gordon Linoff's solution will work. Another way to achieve what you want is to wrap your whole statement in a stored procedure.
this will fail:
select * from nonexisting_table
this will create a stored proc:
create procedure nonsense
as
begin
select * from nonexisting_table
end
BUT there are errors in your query:
SET #cursor = CURSOR FAST_FORWARD
To create a fast forward cursor in sql server you have to declare it.
Thats my favourite example from mssqltips.com:
DECLARE db_cursor CURSOR FAST_FORWARD FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #fileName = #path + #name + '_' + #fileDate + '.BAK'
BACKUP DATABASE #name TO DISK = #fileName
FETCH NEXT FROM db_cursor INTO #name
END
CLOSE db_cursor
DEALLOCATE db_cursor

Passing data into nested cursors in TSQL

I have a cursor that gets data and fetches it into #data_table. Then in the while loop I want to pass that #data_table into another cursor (as the table name) to run some more processing. I keep getting a declare #data_table error. How do I fix this?
DECLARE #var_name varchar(50)
DECLARE #data_table varchar(50)
DECLARE #data_value varchar(50)
DECLARE curDiscreteVars CURSOR LOCAL
FOR SELECT DISTINCT v.var_name, v.data_table
FROM dbo.vars v
GROUP BY v.var_name, v.data_table
-- Loop through cursor, translating variable values as needed, and generate counts for each val_code for a variable
OPEN curDiscreteVars
FETCH NEXT FROM curDiscreteVars
INTO #var_name, #data_table
WHILE ##FETCH_STATUS = 0
BEGIN
--loop through all possible data values
DECLARE curValues CURSOR LOCAL
FOR SELECT DISTINCT #var_name
FROM #data_table
OPEN curValues
FETCH NEXT FROM curValues
INTO #data_value
WHILE ##FETCH_STATUS = 0
BEGIN
print #var_name
FETCH NEXT FROM curValues
INTO #data_value
END
CLOSE curValues
DEALLOCATE curValues
FETCH NEXT FROM curDiscreteVars
INTO #var_name, #data_table
END
CLOSE curDiscreteVars
DEALLOCATE curDiscreteVars
For my part, i don't like cursors! For me cursors are evil. The give you locks and such that you don't want.
What i always do is create a temp table with the values (like you normally insert into the cursor) and loop through it with a while loop
like this :
declare #currow int
, #totrow int
create table #tmp_values (id int identity(1, 1), val int)
insert
into #tmp_values
select val
from tableX
set #totrow = ##rowcount
set #currow = 1
while #totrow > 0 and #currow <= #totrow
begin
select #val = val
from #tmp_values
where id = #currow
set #currow = #currow + 1
end
That way you have more control of things and you can re-use the tmp table
I'm not sure I understand what you're talking about doing, but variables cannot be used as table names. Or, really anything that's not a field name. You'll need to use dynamic SQL. That is, assign your SQL string to a variable, an then run EXEC() command.
For example:
DECLARE #sqlcmd varchar(max)
DECLARE #table_name sysname
DECLARE cur_tables FOR
SELECT name FROM sys.tables
OPEN cur_tables
FETCH NEXT FROM cur_tables INTO #table_name
WHILE ##FETCH_STATUS = 0 BEGIN
SET #sqlcmd = 'SELECT TOP 10 * FROM ' + QUOTENAME(#table_name)
EXEC ( #sqlcmd )
FETCH NEXT from cur_tables INTO #table_name
END
CLOSE cur_tables
DEALLOCATE cur_tables
Alternately, if what you mean is that you need a location to store the data that is like a table, then create a temporary tabled for it.

Nesting stored procedures

I need create a stored proc that will return a list of a code, and then I need to call another stored proc to review each code, one by one.
How can I do this?
CREATE PROCEDURE [dbo].[paBltBuscarBoletasASA] #id_Asa int
AS
DECLARE #Query int, #Contador int
SET #Contador = 0
BEGIN
SET NOCOUNT ON;
SET #Query = (
SELECT
localizacion.c_Fk_IdBoleta
FROM
Blt_Boleta as boleta, Fnc_Localizacion as localizacion
WHERE
boleta.c_Pk_IdBoleta = localizacion.c_Fk_IdBoleta AND
localizacion.si_CodAsa = #id_Asa) //This query give the list of Codes. For example 45550711, 40480711, 80110711... etc
exec dbo.paBltMarcarErroresBoleta #Query //And here I need send one by one that list of Codes
END
You may consider adding an scalar function and call it in your query, like:
SELECT
localizacion.c_Fk_IdBoleta,
dbo.checkCode(localizacion.c_Fk_IdBoleta) as Check
FROM
Blt_Boleta as boleta, Fnc_Localizacion as localizacion
WHERE
boleta.c_Pk_IdBoleta = localizacion.c_Fk_IdBoleta AND
localizacion.si_CodAsa = #id_Asa
Declare a CURSOR for the query that you are setting equal to #Query, and then insert into the variable each subsequent value in a WHILE ##FETCH_STATUS = 0 loop. Then pass the #Query variable to the second stored procedure as you are currently doing. Here is an example:
DECLARE myCursor CURSOR FOR
SELECT localizacion.c_Fk_IdBoleta
FROM Blt_Boleta as boleta, Fnc_Localizacion as localizacion
WHERE boleta.c_Pk_IdBoleta = localizacion.c_Fk_IdBoleta AND
localizacion.si_CodAsa = #id_Asa
OPEN myCursor
FETCH NEXT FROM myCursor INTO #Query
WHILE ##FETCH_STATUS = 0
BEGIN
exec dbo.paBltMarcarErroresBoleta #Query
//do additional processing
FETCH NEXT FROM myCursor INTO #Query
END
CLOSE myCursor
DEALLOCATE myCursor
Additional cursor help: http://msdn.microsoft.com/en-us/library/ms180169.aspx