I have a question for You.
I need an idea to search items in long list of parameters in sql reporting services.
For example there is a houndred of values in list of parameters to select and i have to choose some of them. There exists problem with finding these values because list is too big.
Something searching by first couple letters would be great but probably it is impossible.
Now I really do not know how i could achieve smart method to find couple interested values from list of parameters.
Please help.
For your requirement, I have found an awesome article talking about this with detail solution:
Create a function in your database.
CREATE FUNCTION [dbo].[SplitParameterValues] (#InputString NVARCHAR(max), #SplitChar VARCHAR(5))
RETURNS #ValuesList TABLE
(
param NVARCHAR(255)
)
AS
BEGIN
DECLARE #ListValue NVARCHAR(max)
SET #InputString = #InputString + #SplitChar
WHILE #InputString!= #SplitChar
BEGIN
SELECT #ListValue = SUBSTRING(#InputString , 1, (CHARINDEX(#SplitChar, #InputString)-1))
IF (CHARINDEX(#SplitChar, #InputString) + len(#SplitChar))>(LEN(#InputString))
BEGIN
SET #InputString=#SplitChar
END
ELSE
BEGIN
SELECT #InputString = SUBSTRING(#InputString, (CHARINDEX(#SplitChar, #InputString) + len(#SplitChar)) , LEN(#InputString)-(CHARINDEX(#SplitChar, #InputString)+ len(#SplitChar)-1) )
END
INSERT INTO #ValuesList VALUES( #ListValue)
END
RETURN
END
Use a procedure the get the Available Values, refer to the query below:
create PROCEDURE sp (#keyword nvarchar(50))
AS
SELECT col
FROM table d
inner join (SELECT [param] FROM SplitParameterValues (#keyword,',')) s on d.col like (s.[param]+'%')
Then create a parameter for giving keywords. Then add another cascading parameter based on the key words. For detail steps, please read the source article from the link below:
[Forum FAQ]How do I add a search feature in the parameter with long drop down list?
Related
I have made a stored procedure. I want it to filter the data by different parameters. If I pass one parameter, it should be filtered by one; if I pass two, it should be filtered by two, and so on, but it is not working.
Can anyone help me please?
DROP PROCEDURE IF EXISTS medatabase.SP_rptProvince2;
CREATE PROCEDURE medatabase.`SP_rptProvince2`(
IN e_Region VARCHAR(45)
)
BEGIN
DECLARE strQuery VARCHAR(1024);
DECLARE stmtp VARCHAR(1024);
SET #strQuery = CONCAT('SELECT * FROM alldata where 1=1');
IF e_region IS NOT NULL THEN
SET #strQuery = CONCAT(#strQuery, ' AND (regionName)'=e_Region);
END IF;
PREPARE stmtp FROM #strQuery;
EXECUTE stmtp;
END;
AFAIK, you can't have a variable argument list like that. You can do one of a couple of things:
Take a fixed maximum number of parameters, and check them for null-ness before concatenating:
CREATE PROCEDURE SP_rptProvince2(a1 VARCHAR(45), a2 VARCHAR(45), ...)
...
IF a1 IS NOT NULL THEN
SET #strQuery = CONCAT(#strQuery, ' AND ', a2);
END IF;
If you need predetermined fields to which the criteria in the argument apply (like the e_Region parameter in your existing code), then you modify the CONCAT operation appropriately.
Possible invocation:
CALL SP_rptProvince2('''North''', 'column3 = ''South''')
Take a single parameter that is much bigger than just 45 characters, and simply append it to the query (assuming it is not null).
Clearly, this places the onus on the user to provide the correct SQL code.
Possible invocation:
CALL SP_rptProvince2('RegionName = ''North'' AND column3 = ''South''')
There's not a lot to choose between the two. Either can be made to work; neither is entirely satisfactory.
You might note that there was a need to protect the strings in the arguments with extra quotes; that is the sort of thing that makes this problematic.
I found a JSON-based approach which works with the latest MySQL/MariaDB systems. Check the link below (Original Author is Federico Razzoli): https://federico-razzoli.com/variable-number-of-parameters-and-optional-parameters-in-mysql-mariadb-procedures
Basically, you take a BLOB parameter which is actually a JSON object and then do JSON_UNQUOTE(JSON_EXTRACT(json object, key)) as appropriate.
Lifted an extract here:
CREATE FUNCTION table_exists(params BLOB)
RETURNS BOOL
NOT DETERMINISTIC
READS SQL DATA
COMMENT '
Return whether a table exists.
Parameters must be passed in a JSON document:
* schema (optional). : Schema that could contain the table.
By default, the schema containing this procedure.
* table : Name of the table to check.
'
BEGIN
DECLARE v_table VARCHAR(64)
DEFAULT JSON_UNQUOTE(JSON_EXTRACT(params, '$.table'));
DECLARE v_schema VARCHAR(64)
DEFAULT JSON_UNQUOTE(JSON_EXTRACT(params, '$.schema'));
IF v_schema IS NULL THEN
RETURN EXISTS (
SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE
TABLE_SCHEMA = SCHEMA()
AND TABLE_NAME = v_table
);
ELSE
RETURN EXISTS (
SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE
TABLE_SCHEMA = v_schema
AND TABLE_NAME = v_table
);
END IF;
END;
I wrote a function to generate unique id's,its working but sometimes two people are getting same id,I mean duplicates are formed. My unique id looks like
2016-17NLR250001, I deal with only last four digits 0001. I am posting my function please correct it and please help me in avoiding duplicates even though users login into same account or if they do it on same time.
MY FUNCTION:
DELIMITER $$
USE `olmsap`$$
DROP FUNCTION IF EXISTS `fun_generate_uniqueid`$$
CREATE DEFINER=`root`#`%` FUNCTION `fun_generate_uniqueid`( V_DATE DATE,V_MANDALID INT ) RETURNS VARCHAR(30) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE MDLCODE VARCHAR(5);
SET MDLCODE = ' ';
SELECT COUNT(*) INTO #CNT FROM `st_com_mandal` WHERE MANDAL_VS_MC=V_MANDALID;
SELECT dist_mandal_code INTO MDLCODE FROM `st_com_mandal` WHERE MANDAL_VS_MC=V_MANDALID;
IF #CNT>0 THEN
SET #YR=`FUN_FISCAL_YR`(V_DATE);
SELECT CONCAT(IF(DIST_SAN_CODE='GUN','GNT',DIST_SAN_CODE),IFNULL(`dist_mandal_code`,'NULL'))INTO #MANDAL
FROM `st_com_dist` SCD INNER JOIN `st_com_mandal` STM ON STM.`mandal_dist_id`= SCD.`DIST_VC_DC` WHERE MANDAL_VS_MC=V_MANDALID;
IF MDLCODE >0 THEN
SELECT COUNT(Soil_Sample_ID)+1 INTO #ID FROM `tt_mao_soil_sample_dtls` WHERE MANDAL_ID=V_MANDALID AND SUBSTR(UNIQUE_ID,1,7)=#YR ;
ELSE
SELECT COUNT(Soil_Sample_ID)+1 INTO #ID FROM `tt_mao_soil_sample_dtls` WHERE SUBSTR(UNIQUE_ID,1,14)=CONCAT(#YR,#MANDAL) ;
END IF ;
IF LENGTH(#ID)=1 THEN
SET #ID=CONCAT('000',#ID);
ELSEIF LENGTH(#ID)=2 THEN
SET #ID=CONCAT('00',#ID);
ELSEIF LENGTH(#ID)=3 THEN
SET #ID=CONCAT('0',#ID);
ELSE
SET #ID=#ID;
END IF ;
RETURN CONCAT(#YR,#MANDAL,#ID);
ELSE
RETURN 'Mandal Doesnt Exists';
END IF;
END$$
DELIMITER ;
I do not think community will be able to help you with this question. This is a complex function that requires very careful analysis of table / index access and locking.
The only thing I can recommend is to not use existing table data to calculate next sequence as this is a bad practice.
Besides Race conditions that you are experiencing you will also get problems if the record with the last sequence is deleted.
I suggest you read this to get an idea on how to write a custom sequence generator:
http://en.latindevelopers.com/ivancp/2012/custom-auto-increment-values/
I have searched SO, for similar and I found one other posting similar to this and I followed what I thought was the follow up but I'm still seeing a problem.
I have also been sifting through the MySQL manuals, and what I have here looks like it is correct.
DELIMITER $$
CREATE DEFINER=`perimUser`#`localhost` PROCEDURE `assignLOBId`()
BEGIN
declare id, done INT default 0;
declare name VarChar(45);
declare lobCursor Cursor for Select idLineOfBusiness as id, name from LineOfBusiness;
declare continue handler for not found set done = 1;
OPEN lobCursor;
my_loop: LOOP
FETCH lobCursor INTO id, name;
IF done = 1 THEN
CLOSE lobCursor;
LEAVE my_loop;
END IF;
insert into test values (id, name);
UPDATE medium set idLOB = id where LOB = name;
UPDATE low set idLOB = id where LOB = name;
End LOOP my_loop;
END
I have run the Query that I"m using for the cursor and it does return 13 rows. Tables medium and low are full of data about 600 rows in each. the LOB match values in the LOB column of each. The values that were used to create the ones in lineofbusiness were generated from medium and low.
The goal here is to use this pattern a number of times as I work to normalized the data in medium and low. Otherwise I'd take the short cut and create a bunch of manual update statements.
I'm not too sure why your cursor isn't working as expected (you don't say whether your test table is populated with the results that you expect?), but it appears to me your procedure is simply implementing a multiple-table UPDATE (so can probably be entirely replaced with the following):
UPDATE LineOfBusiness
LEFT JOIN medium ON LineOfBusiness.name = medium.LOB
LEFT JOIN low ON LineOfBusiness.name = low.LOB
SET medium.idLOB = LineOfBusiness.idLineOfBusiness
, low.idLOB = LineOfBusiness.idLineOfBusiness
I have many database instances say for e.g EWB1,EWB2,EWB3 and so on..if suppose I am in EWB1 and I want to access a particular table's column from other nstances (in this case say EWB2,EWB3 and so on).. I am doing something like this
declare #name varchar(10);
DECLARE cur3 CURSOR FOR select EnterpriseDBInstance from [EWB_DAL].[dbo].[Enterprise] where EnterpriseDBInstance <> CONVERT(varchar(10),DB_NAME());
OPEN cur3;
Fetch next from cur3 into #name;
WHILE ##FETCH_STATUS = 0
BEGIN
declare #test varchar(10);
set #test = (select #name);
select ChapterName from [#test].[dbo].[FormData] -- This line is giving error
-- unable to find #test....
Fetch next from cur3 into #name;
END
close cur3;
deallocate cur3;
But I could see EWB2,EWB3... in #test..
You can't use database names dynamically (i.e using variables), in the same way that you can't use table or column names in such a manner.
The query you have is trying to find a database named #test.
You need to look at using dynamic SQL for such work, or rethink your approach. I suggest reading The Curse and Blessings of Dynamic SQL by Erland Sommarskog.
use qoutename like qoutename(ur DB variable name) this works...
I have a table called webqueries with a column named qQuestion of data type text(sql server 2008). I want to create a count on words used in qQuestion (excluding 'and', 'is' etc). My goal is to see how many times a person has asked a question about a specific product.
You could create a table-valued function to parse words and join it to your query against qQuestion. In your schema, I recommend using varchar(8000) or varchar(max) instead of text. Meanwhile, the following should get you started:
create function [dbo].[fnParseWords](#str varchar(max), #delimiter varchar(30)='%[^a-zA-Z0-9\_]%')
returns #result table(word varchar(max))
begin
if left(#delimiter,1)<>'%' set #delimiter='%'+#delimiter;
if right(#delimiter,1)<>'%' set #delimiter+='%';
set #str=rtrim(#str);
declare #pi int=PATINDEX(#delimiter,#str);
while #pi>0 begin
insert into #result select LEFT(#str,#pi-1) where #pi>1;
set #str=RIGHT(#str,len(#str)-#pi);
set #pi=PATINDEX(#delimiter,#str);
end
insert into #result select #str where LEN(#str)>0;
return;
end
go
select COUNT(*)
from webqueries q
cross apply dbo.fnParseWords(cast(q.qQuestion as varchar(max)),default) pw
where pw.word not in ('and','is','a','the'/* plus whatever else you need to exclude */)