【问题标题】:MySQL / Mariadb - Select * from Stored ProcedureMySQL / Mariadb - 从存储过程中选择 *
【发布时间】:2017-12-29 22:45:38
【问题描述】:

我正在尝试使用 UF Dashbuilder 向我的 SQL 查询添加语法,但我不知道如何更正它。

有效的调用类似于:

call database.report ('1234', 'txt');

Dashbuilder 把它变成这个不起作用:

 SELECT * FROM (call database.report ('1234', 'txt');) AS `dbSQL` LIMIT 1

我也可以使用存储过程末尾的代码将结果存储在表中,然后在 Dashbuilder 中使用SELECT * FROM TABLE,但我不知道如何将结果存储在表中(动态数列)。

您能否告诉我如何使用添加的 SELECT * 使存储过程工作,或者如何将该代码的结果存储在表中?

  SET @sql = NULL;
   SET SESSION GROUP_CONCAT_MAX_LEN = 1000000;  -- default is 1024
   SELECT
      GROUP_CONCAT(DISTINCT
         CONCAT(
            'MAX(IF(question = ''', REPLACE(question,"'", "\\'"), ''', answer, NULL)) AS ''', REPLACE(question,"'", "\\'"), ''''
         )
      ) INTO @sql
      FROM tmp2;

      SET @sql = CONCAT('SELECT id, datestamp, ', @sql, ' FROM tmp2 GROUP BY id');

      -- SELECT @sql;   

      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;  

更新 1。 对答案 1 的评论: 来自原始@SQL 的结果:

`SET @sql = CONCAT('SELECT id, datestamp, ', @sql, ' FROM tmp2 GROUP BY id');`


SELECT id, datestamp, MAX(IF(question = '1. Our records show that you got care from the provider named below in the last 6 months. {Provider}.  Is that right?', answer, NULL)) 
   AS '1. Our records show that you got care from the provider named below in the last 6 months. {Provider}.  Is that right?',
   MAX(IF(question = '2. Is this the provider you usually see if you need a check-up, want advice about a health problem, or get sick or hurt?', answer, NULL)) 
   AS '2. Is this the provider you usually see if you need a check-up, want advice about a health problem, or get sick or hurt?',
   MAX(IF(question = 'Area', answer, NULL)) AS 'Area',MAX(IF(question = 'Encounter', answer, NULL)) AS 'Encounter' FROM tmp2 GROUP BY id

@SQL 的结果:

错误:错误代码:1166。列名 '1 不正确。我们的记录显示,您在过去 6 个月内从以下指定的提供者处获得了护理。 {提供者}'

我猜有一个它不喜欢的字符,例如单引号?

SET @tableName = 'myreport';
SET @sql = CONCAT('CREATE TABLE ', @tableName, ' AS SELECT id, datestamp, ', @sql, ' FROM tmp2 GROUP BY id');


CREATE TABLE myreport AS SELECT id, datestamp, MAX(IF(question = '1. Our records show that you got care from the provider named below in the last 6 months. {Provider}.  Is that right?', answer, NULL)) 
   AS '1. Our records show that you got care from the provider named below in the last 6 months. {Provider}.  Is that right?',
   MAX(IF(question = '2. Is this the provider you usually see if you need a check-up, want advice about a health problem, or get sick or hurt?', answer, NULL)) 
   AS '2. Is this the provider you usually see if you need a check-up, want advice about a health problem, or get sick or hurt?',
   MAX(IF(question = 'Area', answer, NULL)) AS 'Area',MAX(IF(question = 'Encounter', answer, NULL)) AS 'Encounter' FROM tmp2 GROUP BY id

更新 2: 这行得通!谢谢! 我必须减少列名的长度,如下所示。然后我可以每天运行两次存储过程并在 Dashbuilder 中从该表中选择 *。

CREATE TABLE myreport AS SELECT id, datestamp, MAX(IF(question = '1. Our records show that you got care from the provider named below in the last 6 months. {Provider}.  Is that right?', answer, NULL)) 
   AS '1.',
   MAX(IF(question = '2. Is this the provider you usually see if you need a check-up, want advice about a health problem, or get sick or hurt?', answer, NULL)) 
   AS '2.',
   MAX(IF(question = 'Area', answer, NULL)) AS 'Area',MAX(IF(question = 'Encounter', answer, NULL)) AS 'Encounter' FROM tmp2 GROUP BY id

更新 3:这行得通!谢谢!

   SET @t = CONCAT('DROP TABLE IF EXISTS ', survey_report );
   PREPARE stmt FROM @t;
   EXECUTE stmt;
   DEALLOCATE PREPARE stmt;

   SET @sql = NULL;
   SET SESSION GROUP_CONCAT_MAX_LEN = 1000000;  -- default is 1024
   SELECT
      GROUP_CONCAT(DISTINCT
         CONCAT(  
            'MAX(IF(question = ''', REPLACE(question,"'", "\\'"), ''', answer, NULL)) AS ''', REPLACE(udf_clean_column_name(15, udf_remove_tags(question)),"'", "\\'"), ''''
         )
      ) INTO @sql
      FROM tmp2;

      SET @sql = CONCAT('CREATE TABLE ', survey_report, ' AS SELECT id, datestamp, ipaddr, ', @sql, ' FROM tmp2 GROUP BY id');

      -- SELECT @sql;

      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;   

   DROP TEMPORARY TABLE IF EXISTS `survey_lookup`;
   DROP TEMPORARY TABLE IF EXISTS `tmp`;
   DROP TEMPORARY TABLE IF EXISTS `tmp2`;

Mysql 函数去除列名中的空格等。

CREATE FUNCTION `udf_clean_column_name`(col_name_len INT, str varchar(200)) RETURNS varchar(200)
    BEGIN
       SET str = SUBSTRING(str,1,col_name_len);
       SET str = TRIM(str);
       SET str = Replace(str,' ','_');
       SET str = Replace(str,'-','');
       SET str = Replace(str,'?','');
       SET str = Replace(str,',','');
       SET str = Replace(str,'.','');
       RETURN str;
    END;

删除标签的Mysql函数(我不记得我从哪里得到这个函数)。

CREATE FUNCTION `udf_remove_tags`(Dirty varchar(4000))
RETURNS varchar(4000)
    DETERMINISTIC
    BEGIN
      DECLARE iStart, iEnd, iLength int;
        WHILE Locate( '<', Dirty ) > 0 And Locate( '>', Dirty, Locate( '<', Dirty )) > 0 DO
          BEGIN
            SET iStart = Locate( '<', Dirty ), iEnd = Locate( '>', Dirty, Locate('<', Dirty ));
            SET iLength = ( iEnd - iStart) + 1;
            IF iLength > 0 THEN
              BEGIN
                SET Dirty = Insert( Dirty, iStart, iLength, '');
                set Dirty = Replace(Dirty,'&nbsp;',''); #No space between & and nbsp;
                set Dirty = Replace(Dirty,'\r','');
                set Dirty = Replace(Dirty,'\n','');
              END;
            END IF;
          END;
        END WHILE;
        RETURN Dirty;
    END;

【问题讨论】:

标签: mysql stored-procedures prepared-statement mariadb


【解决方案1】:

我在 UF DashBuilder 文档中没有看到任何提及存储过程的内容,所以看起来他们没有办法解决这个问题。

您可以从SELECT 查询创建表。如果您省略列规范,它们将自动从查询的选择列表中派生。

SET @sql = CONCAT('CREATE TABLE ', tableName, ' AS
    SELECT id, datestamp, ', @sql, ' FROM tmp2 GROUP BY id');
PREPARE stmt FROM @sql
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

【讨论】:

  • 谢谢。 Dashbuilder 的早期版本允许存储过程。我无法找到他们在代码中添加语法的位置。我收到了这个错误:Error Code: 1166. Incorrect column name '1. Our records show that you got care from the provider named below in the last 6 months.
  • 我对这个库不是很熟悉,但可能有不同的调用来返回一行或所有行。他们添加的包装器旨在将结果限制为单行。
  • 非常感谢您的帮助。我在原始问题中添加了更多文本,因为此框没有提供足够的空间。
猜你喜欢
  • 2010-12-10
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 2020-01-10
  • 2011-01-07
  • 2010-12-02
  • 1970-01-01
相关资源
最近更新 更多