Может быть, это глупо, я являюсь разработчиком Microsoft SQL / C # и никогда раньше не использовал никакие другие IDE / написанные JAVA / SCALA.Я переношу некоторые SQL-запросы Azure в решение Azure Databricks.
Похоже, что нет эквивалента функции TSQL DATEDIFF_BIG (https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-2017)
Решения, которые вы найдете, - запрограммируйте свой собственный UDF.
То, что я сделал (см. Ниже) в записной книжке SCALA - отлично работает для временной функции. (https://docs.databricks.com/spark/latest/spark-sql/language-manual/create-function.html)
Это был самый полезный образец, который я нашел https://github.com/johnmuller87/spark-udf.
Существует множество примеров временных функций, но я не нашел постоянных функций для разработчиков, не являющихся JAVA / SCALA.
Я установил SBT (Последняя версия для Windows - https://www.scala-sbt.org/1.x/docs/Install-sbt-on-Windows.html) Я также установил Intellj
Я запускаю SBT BUILT для образца IBAN, но не могу получитьФункция SQL, после загрузки JAR в мой Clusterd и регистрации функции для работы.
CREATE FUNCTION ValidateIBAN AS 'com.ing.wbaa.spark.udf.ValidateIBAN' USING JAR 'spark_udf_assembly_0_2_0' --without extension
SELECT ValidateIBAN('NL20INGB0001234567')
Ошибка всегда была "Ошибка в выражении SQL: AnalysisException: Нет обработчика для UDF / UDAF / UDTF 'com.ing.wbaa.spark.udf.ValidateIBAN ';строка 1 поз 7 "
//import org.apache.spark.sql.types._ // include the Spark Types to define our schema
import org.apache.spark.sql.types.LongType
import org.apache.spark.sql.functions.udf
import java.time.temporal.ChronoUnit;
// Define function to calculate local time offset
def getTimestampDifference(interval: java.lang.String, date1: java.sql.Timestamp, date2: java.sql.Timestamp) : java.lang.Long = {
//https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html
//https://spark.apache.org/docs/2.4.0/sql-reference.html
//https://alvinalexander.com/scala/how-to-use-scala-match-expression-like-switch-case-statement
interval match
{
case "NANOSECOND"=> return ChronoUnit.NANOS.between(date1.toInstant(), date2.toInstant());
case "MICROSECOND"=> return ChronoUnit.MICROS.between(date1.toInstant(), date2.toInstant());
case "MILLISECOND"=> return ChronoUnit.MILLIS.between(date1.toInstant(), date2.toInstant()); // date2.getTime() - date1.getTime();
case "SECOND"=> return ChronoUnit.SECONDS.between(date1.toInstant(), date2.toInstant());
case "MINUTE"=> return ChronoUnit.MINUTES.between(date1.toInstant(), date2.toInstant());
case "HOUR"=> return ChronoUnit.HOURS.between(date1.toInstant(), date2.toInstant());
case "DAY"=> return ChronoUnit.DAYS.between(date1.toInstant(), date2.toInstant());
case "WEEK"=> return ChronoUnit.WEEKS.between(date1.toInstant(), date2.toInstant());
case "MONTH"=> return ChronoUnit.MONTHS.between(date1.toInstant(), date2.toInstant());
case "YEAR"=> return ChronoUnit.YEARS.between(date1.toInstant(), date2.toInstant());
}
}
spark.udf.register("DATETIMEDIFF", udf(getTimestampDifference(_:java.lang.String, _:java.sql.Timestamp,_:java.sql.Timestamp),LongType))
На самом деле мне нужно - как преобразовать ноутбук SCALA в функцию SQL, чтобы я мог использовать его в постоянном представлении SQL в кластере баз данных Azure версии 5.4 (включая Apache)Spark 2.4.3, Scala 2.11)
- Какой класс для реализации
- Какой метод реализовать (переопределить в c #) - есть также разные статьи о HIVE или SPARK
- Как настроить встроенный SBT или любой другой способ скомпилировать его в Java-архиве, чтобы я мог успешно создавать и запускать функцию SQL (только в SQL, а не в коде Pyhton или в Scala-коде - в блокноте SQL)
Спасибо за помощь