如何在HIVE脚本中设置变量

时间:2012-09-17 17:51:52

标签: hive hiveql

我正在寻找Hive QL中SET varname = value的SQL等价物

我知道我可以这样做:

SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE

但后来我收到了这个错误:

  

此处不支持字符'@'

10 个答案:

答案 0 :(得分:179)

您需要使用特殊的 hiveconf 进行变量替换。 e.g。

hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'

同样,您可以传递命令行:

% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql

请注意,还有 env 系统变量,因此您可以参考${env:USER}

要查看所有可用变量,请从命令行运行

% hive -e 'set;'

或从配置单元提示符运行

hive> set;

<强>更新 我也开始使用 hivevar 变量,将它们放入hql片段中,我可以使用source命令从hive CLI中包含(或从命令行传递-i选项)。 这里的好处是,变量可以在有或没有hivevar前缀的情况下使用,并允许类似于全局和本地使用的东西。

因此,假设有一些 setup.hql 设置了一个tablename变量:

set hivevar:tablename=mytable;
然后,我可以带进蜂巢:

hive> source /path/to/setup.hql;

并在查询中使用:

hive> select * from ${tablename}

hive> select * from ${hivevar:tablename}

我还可以设置一个“本地”表名,这会影响$ {tablename}的使用,但不会影响$ {hivevar:tablename}

hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'

VS

hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'

可能并不意味着从CLI过多,但可以在使用 source 的文件中使用hql,但是将一些变量“本地”设置为在脚本的其余部分中使用。

答案 1 :(得分:6)

您是否尝试过使用美元符号括号

SELECT * 
FROM foo 
WHERE day >= '${CURRENT_DATE}';

答案 2 :(得分:6)

这里的大多数答案都建议使用hiveconfhivevar命名空间来存储变量。所有这些答案都是正确的。但是,还有一个名称空间。

总共有三个namespaces可用于保存变量。

  1. hiveconf -hive从此开始,所有hive配置都存储为该conf的一部分。最初,变量替换不是蜂巢的一部分,当它引入时,所有用户定义的变量也都作为变量的一部分存储。这绝对不是一个好主意。因此,又创建了两个名称空间。
  2. hivevar :存储用户变量
  3. 系统:用于存储系统变量。

因此,如果您将变量存储为查询的一部分(即日期或product_number),则应使用hivevar名称空间而不是hiveconf名称空间。

这就是它的工作方式。

hiveconf 仍然是默认名称空间,因此,如果您不提供任何名称空间,它将在hiveconf名称空间中存储您的变量。

但是,当涉及到引用变量时,事实并非如此。默认情况下,它引用 hivevar 名称空间。令人困惑,对不对?通过以下示例,它会变得更加清晰。

如果您如下所述不提供名称空间,则变量var将存储在hiveconf名称空间中。

set var="default_namespace";

因此,要访问此文件,您需要指定 hiveconf名称空间

select ${hiveconf:var};

如果不提供名称空间,则会出现以下错误,原因是默认情况下,如果您尝试访问仅在hivevar名称空间中检查的变量。在hivevar中没有名为var

的变量
select ${var}; 

我们已经明确提供了hivevar命名空间

set hivevar:var="hivevar_namespace";

当我们提供命名空间时,它将起作用。

select ${hivevar:var}; 

默认情况下,引用变量时使用的工作空间为hivevar,以下内容也将起作用。

select ${var};

答案 3 :(得分:2)

要注意的一件事是设置字符串,然后再引用它们。您必须确保引号不会冲突。

 set start_date = '2019-01-21';
 select ${hiveconf:start_date}; 

必须谨慎设置日期,然后在代码中引用它们,因为字符串可能会发生冲突。不适用于上面设置的start_date。

 '${hiveconf:start_date}'

设置带有引号和结束引号的变量时。我们必须注意,在查询中返回时不要对字符串设置双引号或双引号。

答案 4 :(得分:1)

两种简单的方法:

使用配置单元配置

JTabbedPane.setSelectedIndex(1);

使用配置单元变量

在您的CLI上设置var,然后在配置单元中使用它们

hive> set USER_NAME='FOO';
hive> select * from foobar where NAME = '${hiveconf:USER_NAME}';

文档: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution

答案 5 :(得分:1)

以防万一有人需要通过cli参数化配置单元查询。

例如:

hive_query.sql

SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'

现在从cli执行以上sql文件:

hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql

答案 6 :(得分:1)

在 Hive 中有多种设置变量的选项。

如果您想从 Hive shell 内部设置 Hive 变量,您可以使用 hivevar 设置它。您可以设置字符串或整数数据类型。他们没有问题。

SET hivevar:which_date=20200808;
select ${which_date};

如果您打算从 shell 脚本设置变量并希望将这些变量传递到您的 Hive 脚本 (HQL) 文件中,您可以在调用 hive 或 beeline 命令时使用 --hivevar 选项。

# shell script will invoke script like this
beeline --hivevar tablename=testtable -f select.hql
-- select.hql file
select * from <dbname>.${tablename};

答案 7 :(得分:0)

尝试此方法:

 @IBAction func saveandcontinue(_ sender: UIButton) {


        self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).child("ProfilePic").observe(DataEventType.value) { (snapshot) in
            let profpic = snapshot.value as? String
            if profpic != nil  && self.fullname.text != nil{

               self.savefavapps()
                let newfullname = Story(fullname: self.fullname.text!)

                newfullname.save()
                //                if self.bio.text != nil {
//                    self.databaseRef.child("ProfileInfo").child(Auth.auth().currentUser!.uid).updateChildValues(["Bio": self.bio.text!])
//                }
                self.performSegue(withIdentifier: "createtoprofile", sender: nil)
            }else {
                print("require name and picture")

            }





          }


@IBAction func addprofilepic(_ sender: Any) {
        picker.allowsEditing = false
        picker.sourceType = .photoLibrary
        picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
        present(picker, animated: true, completion: nil)


    }
    @objc func imagePickerController(_ picker: UIImagePickerController,
                                       didFinishPickingMediaWithInfo info: [String : AnyObject])     {

        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
        profilepic.contentMode = .scaleAspectFit //3
        profilepic.image = chosenImage //4

        dismiss(animated: true, completion: nil)
        var data = NSData()
        data = UIImageJPEGRepresentation(profilepic.image!, 0.8)! as NSData
        // set upload path
        let filePath = "\("ProfilePic")/\(Auth.auth().currentUser!.uid)"
        let metaData = StorageMetadata()
        metaData.contentType = "image/jpg"
        self.storageRef.child(filePath).putData(data as Data, metadata: metaData){(metaData,error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }else{
                //store downloadURL
                let downloadURL = metaData!.downloadURL()!.absoluteString
                //store downloadURL at database
                let imageurl = Story(profimage:downloadURL)

                imageurl.save()
            }

        }
    }

在我的平台上效果很好。

答案 8 :(得分:0)

您可以在shell脚本中导出变量 出口CURRENT_DATE =“ 2012-09-16”

然后在您喜欢的hiveql中 SELECT * FROM foo WHERE day> ='$ {env:CURRENT_DATE}'

答案 9 :(得分:-7)

您可以将另一个查询的输出存储在变量中,然后您可以在代码中使用相同的内容:

set var=select count(*) from My_table;
${hiveconf:var};