Here is the following piece of code that I am trying to execute on SQL Server.
DECLARE #string NVARCHAR(MAX) = '
CREATE PROC [dbo].[Trend]
#slsID NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON
DECLARE #BeginningRange varchar(20),
#EndingRange varchar(20)
SET #EndingRange = ''12*13''
SET #BeginningRange = ''12*02''
;WITH CTE1 AS(
SELECT
dbo.Field1,dbo.Field2,dbo.Field3
FROM dbo.Table1 join dbo.Table2 where...conditions
weekNum BETWEEN (#BeginningRange) AND (#EndingRange)
)
SELECT * FROM CTE1
UNPIVOT
( numbers for type in (Field1, Field2, Field3, Field4)
) as p PIVOT
(
Sum(numbers) for
WeekNum in ([12*02],[12*03],[12*04],[12*05],[12*06],[12*07],[12*08],[12*09],[12*10], [12*11],[12*12],[12*13])
) as q
END
'
EXECUTE SP_EXECUTESQL #STRING
When I try to run this, it errors out saying that
"Incorrect syntax near the keywor 'as'"
I took this code out and executed it separately and it didn't error out. Am I missing something here?
Look like missing parentheses around the parameter to the procedure.
One trick you can use is the print out the sql statement and then try to run that - the error message might give you more info
print #STRING
PIVOT and UNPIVOT clauses each require two closing parentheses.
UNPIVOT (... FOR ... IN (...) ) AS ...
PIVOT (... FOR ... IN (...) ) AS ...
where...conditions
This won't pass a syntax check. If you have removed the actual conditions it may be that this is where your error is. And:
dbo.Table1 join dbo.Table2
has no ON clause
I saw both of these by doing a syntax check on the results of print #string which is the first step you should have taken to find the issue. I still say that based on what you gave us there is no reason at all to use dynamic SQl and it is a poor practice to use dynamic SQL if you don't need it.
Related
so i have 2 tables as table1 and table2 in 2 different databases as id_information and id_information_backup. Both the tables have the following columns: (id bigint, name varchar, surname varchar) I made this trigger where when the user enters name and surname in table1 , it calculates the ascii code of it and do some calculations and store it in the "name" column of the second table which is "table2". All of these has been done in Mysql workbench. when i import the code into phpmyadmin then it gives me too many syntax errors. I tried to figure what syntax errors do i have but i could not find. I am sharing the trigger below. Kindly help me if you can. I will really appreciate it. I guess it is because of the version that i used is MySQL workbench 8.0 and the version that i am importing this into is PHPmyadmin 4.9.4 . Fix the problem if you can please.
delimiter $$
CREATE DEFINER = CURRENT_USER TRIGGER `id_information`.`table1_after_INSERT1` AFTER INSERT ON `table1` FOR EACH ROW
BEGIN
declare p , r , copy, result, result1 decimal(64,0);
declare name1, surnam varchar(15);
declare a int;
set name1 = new.name;
set surnam = new.surname;
set a= 100;
set result =0;
set copy = 0;
set result1 =0;
set p =0 ;
set r =0 ;
with recursive cte as (
select name1 as name1, left(name1, 1) as val, 1 as idx
union all
select name1, substring(name1, idx + 1, 1), idx + 1
from cte
where idx < char_length(name1)
)
select group_concat(ascii(val) + a order by idx separator '') ascii_word from cte into result;
with recursive ctee as (
select surnam as surnam, left(surnam, 1) as vall , 1 as idxx
union all
select surnam, substring(surnam, idxx+ 1, 1), idxx+ 1
from ctee
where idxx< char_length(surnam)
)
select group_concat(ascii(vall ) + a order by idxx separator '') ascii_word from ctee into result1;
select group_concat(result, result1) into copy;
insert into id_information_backup.table2 set table2.name = copy;
END$$
delimiter ;
When you try to run the command (by pressing the "Go" button at the bottom of the SQL text area), what happens?
If phpMyAdmin is showing the errors as red circles with a white x to the left of the SQL area before submitting, then these are syntax warnings that won't affect your ability to submit the query. These are provided as hints by the SQL linter in phpMyAdmin.
phpMyAdmin syntax warning:
If the errors come after submitting the statements, then the errors come from MySQL itself and aren't directly caused by phpMyAdmin.
MySQL syntax error:
In PHPMyAdmin you need to set up delimiter in a small box under the main query
It should be signed as "Delimiter" ;-)
I ended getting caught by that one a few time :-D
I have a stored procedure in MSSQl, i would like to write it int My sql,
Any help or sugegstions please.I can not get to use XML function in Mysql.
stored proc:
ALTER PROCEDURE uspGetProductDetailsCSV (
#sku NVARCHAR(MAX)
)
AS
BEGIN
-
SELECT T.C.value('.', 'NVARCHAR(100)') AS [SKU]
INTO #tblPersons
FROM (SELECT CAST ('<Name>' + REPLACE (#sku, ',', '</Name><Name>')
+ '</Name>' AS XML) AS [Products]) AS A
CROSS APPLY Products.nodes('/Name') as T(C)
SELECT *
FROM ProductInformation Pr
WHERE EXISTS (SELECT Name FROM #tblPersons tmp WHERE tmp.SKU
= case when len(tmp.SKU) = 11 then Product_No+Colour_Code+Size_Code
when len(tmp.SKU) = 8 then Product_No+Colour_Code
when len(tmp.sku) = 6 then Product_No end)
DROP TABLE #tblPersons
END
Edit: I could not write XML part of stored proc, as i have pasted same code in Mysql, it doesnt create stored proc
Error: >can not cast as XML<
I dont believe XML is a valid type in MySql. Try just leaving it as a VARCHAR.
So, just remove the cast...I also think you will have to use CONCAT instead of + and change the [] around columns to ticks.
So Instead of:
FROM (SELECT CAST ('<Name>' + REPLACE (#sku, ',', '</Name><Name>')
+ '</Name>' AS XML) AS [Products]) AS A
TRY:
FROM (SELECT CONCAT('<Name>' , REPLACE(#sku, ',', '</Name><Name>'),
'</Name>') AS `Products`) AS A
I know that there are several ways to find which row's column contains a string, like using [column name] regexp ' ' or [column name] like ' '
while currently what I need some help is I have a table with several columns, all of there are varchar or text and I am not sure which column contains a certain string. Just say that I want to search a "xxx from a table. Several different columns could contain this string or not. Is there a way that I could find which column contains this string?
I have a thinking and the solution could be
select * from [table name] where [column1] regexp 'xxx' or
[column2] regexp 'xxx' or ...... [column39] regexp 'xxx' or .....
[colum60] regexp 'xxx' or ... or [column 80] regexp 'xxx';
I do not want the query like this. Is there another effective way?
To give a better example, say that we are searching for a table that belongs to a blog.
We have title, URL, content, key words, tag, comment and so on. Now we just say, if any blog article is related to "database-normalization", this word may appear in the title, URL or content or anywhere, and I do not want to write it one by one like
where title regexp 'database-normalization' or content regexp 'database-normalization' or url regexp 'database-normalization'......
as when there are hundreds columns, I need to write a hundred, or in this case is there an effective way instead of write hundred or statement? Like using if-else or collections or some others to build the query.
If you want a pure dynamic way, you can try this. I've tried it long back on sql-server and hope it may help you.
#TMP_TABLE -- a temporary table
- PK, IDENTITY
- TABLE_NAME
- COLUMN_NAME
- IS_EXIST
INSERT INTO #TMP_TABLE (TABLE_NAME,COLUMN_NAME)
SELECT C.TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.TABLE_NAME = <your-table> AND C.DATA_TYPE = 'varchar'; -- you can modify it to handle multiple table at once.
-- boundaries
SET #MINID = (SELECT ISNULL(MIN(<PK>),0) FROM #TMP_TABLE );
SET #MAXID = (SELECT ISNULL(MAX(<PK>),0) FROM #TMP_TABLE );
WHILE ((#MINID<=#MAXID) AND (#MINID<>0))
BEGIN
SELECT #TABLE_NAME = TABLE_NAME,#COLUMN_NAME = COLUMN_NAME
FROM #TMP_TABLE
WHERE <PK> = #MINID;
SET #sqlString = ' UPDATE #TMP_TABLE
SET IS_EXIST = 1
WHERE EXIST (SELECT 1 FROM '+ #TABLE_NAME+' WHERE '+ #COLUMN_NAME +' = ''demo.webstater.com'') AND <PK> = '+ #MINID;
EXEC(#sql) ;
SET #MINID = (SELECT MIN(<PK>) FROM #TMP_TABLE WHERE <PK> > #MINID );
END
SELECT * FROM #TMP_TABLE WHERE IS_EXIST = 1 ; -- will give you matched results.
If you know the columns in advance, what you proposed is probably the most effective way (if a little verbose).
Otherwise, you could get the column names from INFORMATION_SCHEMA.COLUMNS and construct dynamic SQL based on that.
His question is not to query specific columns with like clause. He has been asking to apply same pattern across columns dynamically.
Example: Table having 3 columns - FirstName, LastName, Address and pattern matching is "starts with A" then resulting query should be:
Select * From Customer where FirstName like 'A%" or LastName like 'A%" or Address like 'A%'
If you want to build query in business layer, this could easily be done with reflection along with EF.
If you are motivated to do in database then you can achieve by building query dynamically and then execute through sp_executesql.
Try this (Just pass tablename and the string to be find)-:
create proc usp_findString
#tablename varchar(500),
#string varchar(max)
as
Begin
Declare #sql2 varchar(max),#sql nvarchar(max)
SELECT #sql2=
STUFF((SELECT ', case when '+QUOTENAME(NAME)+'='''+#string+''' then 1 else 0 end as '+NAME
FROM (select a.name from sys.columns a join sys.tables b on a.[object_id]=b.[object_id] where b.name=#tablename) T1
--WHERE T1.ID=T2.ID
FOR XML PATH('')),1,1,'')
--print #string
set #sql='select '+#sql2+' from '+#tablename
print #sql
EXEC sp_executesql #sql
End
SQL Server 2014
One way is to use CASE to check the substring existence with LOCATE in mysql and return the column but all you have to check in every column of the table as below:
CREATE TABLE test(col1 VARCHAR(1000), col2 VARCHAR(1000), col3 VARCHAR(1000))
INSERT INTO test VALUES
('while currently what I need some help is I have a table with 10 columns',
'contains a certain string. Just say that I want to search a table',
'contains a certain string demo.webstater.com')
SELECT (CASE WHEN LOCATE('demo.webstater.com', col1, 1) > 0 THEN 'col1'
WHEN LOCATE('demo.webstater.com', col2, 1) > 0 THEN 'col2'
WHEN LOCATE('demo.webstater.com', col3, 1) > 0 THEN 'col3'
END) whichColumn
FROM test
OUTPUT:
whichColumn
col3
There are many ways in which you can do your analysis. You can use "LIKE A%%" if it starts from A in SQL, "REGEX" LibrarY for multiple checks.
So i am trying to do ltrim or rtrim in a sql statement without having to explicitly type all the column names. So basically instead of doing
select ltrim(col1), ltrim(col2)... from table 1
i want to do something like
select ltrim(*) from table1.
I understand that typically it is bad practice to use select * but in this case it makes sense. This is for Sql-server 2008. There are some similar questinos but could not find question for this particular issue. Thanks for help in advance.
you can dynamically create the query or make a stored procedure in which you pass the table name..
DECLARE #colsUnpivot AS NVARCHAR(MAX)
,#tablename as varchar(255)='table1',
#columns as varchar (max),
#SQL VARCHAR(max)
select #colsUnpivot = stuff((select ',LTRIM('+quotename(C.name)+')'
from sys.columns as C
where C.object_id = object_id(#tablename) and
C.is_computed=0
for xml path('')), 1, 1, '')
SET #columns=#colsUnpivot
SET #SQL = '(SELECT '+#columns+' FROM [dbo].['+#tablename+'] )';
EXEC(#SQL)
I'm getting a severe error - code 20, from a Merge statement and I am not sure why. The MERGE runs fine if I remove the OUTPUT $action clause, and updates/inserts the target table as expected. As soon as I put the OUTPUT clause in, either as a simple OUTPUT $action or storing it in a table variable and selecting from that, it causes an error level 20. I am using two CTEs for the target and source. Not sure if that's contributing to the issue, but as I said, it works fine without an OUTPUT clause. Using SQL Server 2008. I've removed most of the columns for readability here.
USE [DM]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MergeMDATEST]
#InsertAuditKey INT = 10
,#UpdateAuditKey INT = 1
AS
SET NOCOUNT ON;
DECLARE #RowCounts TABLE (mergeAction varchar(20));
--------------------------------------------
--- CTEs to add in Binary_Checksum Calcs ---
WITH SourceQuery AS
(
SELECT TOP 100
[Company]
,[AccountNumber]
,BINARY_CHECKSUM([Company]) As [Checksum]
FROM #temptestMergeSource
)
,TargetTable AS
(
SELECT TOP 100
[Company]
,BINARY_CHECKSUM([Company]) As [Checksum]
FROM #temptestMergeTarget
)
MERGE TargetTable AS Target
USING SourceQuery As Source
ON (
Target.[AccountIndex] = Source.[AccountIndex]
AND Target.[CodeID] = Source.[CodeID]
AND Target.[GroupID] = Source.[GroupID]
)
WHEN MATCHED AND (Target.[Checksum] <> Source.[Checksum]) THEN
UPDATE SET
[AccountNumber] = Source.[AccountNumber]
,[AuditKey] = #UpdateAuditKey
WHEN NOT MATCHED THEN
INSERT (
[Company]
,[AuditKey]
)
VALUES (
Source.[Company]
,#InsertAuditKey
)
OUTPUT $action INTO #RowCounts;
SELECT * FROM #RowCounts
-----RowCounts returned for auditing
--SELECT
-- COUNT(CASE WHEN mergeAction = 'Insert' THEN 1 ELSE 0 END) As [INSERT]
-- ,COUNT(CASE WHEN mergeAction = 'Update' THEN 1 ELSE 0 END) As [UPDATE]
--FROM #RowCounts
A calculated column in a CTE Target combined with an output clause results in a fatal error. Bug submission on Microsoft Connect