sqlpostgresqlplpgsqlrdbmssql-function

PostgreSQL function has syntax error at IF. Why?


I was trying to write a function: If a row exists it returns the row with a flag 'Exists'; otherwise it inserts a row and returns it with a flag 'New'.

But I am facing a syntax error:

ERROR:  syntax error at or near "IF"
LINE 11:   IF EXISTS (
           ^
SQL state: 42601
Character: 208
CREATE FUNCTION create_food_type (
  foodTypeName TEXT,
  foodTypeIsActive BOOLEAN,
  foodTypeCreatedBy INT,
  foodTypeModifiedBy INT
)
RETURNS TABLE (operation TEXT, result JSON)
LANGUAGE SQL
AS $$
BEGIN
  IF EXISTS (
    SELECT *
    FROM "FoodType"
    WHERE "FoodTypeName" = foodTypeName
  ) THEN
    -- Return the existing row and flag indicating row already exists
    RETURN QUERY (
      SELECT 'existing' AS operation, json_build_object(
        'FoodTypeId', "FoodTypeID",
        'FoodTypeName', "FoodTypeName",
        'FoodTypeIsActive', "FoodTypeIsActive",
        'FoodTypeCreatedDate', "FoodTypeCreatedDate",
        'FoodTypeCreatedBy', "FoodTypeCreatedBy",
        'FoodTypeModifiedDate', "FoodTypeModifiedDate",
        'FoodTypeModifiedBy', "FoodTypeModifiedBy"
      )
      FROM "FoodType"
      WHERE "FoodTypeName" = foodTypeName
      LIMIT 1
    );
  ELSE
    -- Insert a new row and return the newly inserted row and flag indicating new row added
    RETURN QUERY (
      INSERT INTO "FoodType" ("FoodTypeName", "FoodTypeIsActive", "FoodTypeCreatedDate", "FoodTypeCreatedBy", "FoodTypeModifiedDate", "FoodTypeModifiedBy")
      VALUES (foodTypeName, foodTypeIsActive, CURRENT_TIMESTAMP, foodTypeCreatedBy, CURRENT_TIMESTAMP, foodTypeModifiedBy)
      RETURNING 'new' AS operation, json_build_object(
        'FoodTypeId', "FoodTypeID",
        'FoodTypeName', "FoodTypeName",
        'FoodTypeIsActive', "FoodTypeIsActive",
        'FoodTypeCreatedDate', "FoodTypeCreatedDate",
        'FoodTypeCreatedBy', "FoodTypeCreatedBy",
        'FoodTypeModifiedDate', "FoodTypeModifiedDate",
        'FoodTypeModifiedBy', "FoodTypeModifiedBy"
      )
    );
  END IF;
END;
$$;

I tried CASE WHEN:

 IF EXISTS (
    SELECT *
    FROM "FoodType"
    WHERE "FoodTypeName" = foodTypeName
  ) THEN
--Do Something
 ELSE
--Do Something
 END IF;

That throws the same error at 'CASE'.


Solution

  • The body language should be plpgsql, also add suffix to your parameters for better readability :

    CREATE FUNCTION create_food_type (
      p_foodTypeName TEXT,
      p_foodTypeIsActive BOOLEAN,
      p_foodTypeCreatedBy TEXT,
      p_foodTypeModifiedBy TEXT
    )
    RETURNS TABLE (operation TEXT, result JSON)
    AS $$
    DECLARE
      operation text default 'existing';
    BEGIN
      IF NOT EXISTS (
        SELECT *
        FROM FoodType
        WHERE FoodTypeName = p_foodTypeName
      ) THEN
          operation = 'new';
          INSERT INTO FoodType (FoodTypeName, FoodTypeIsActive, FoodTypeCreatedDate, FoodTypeCreatedBy, FoodTypeModifiedDate, FoodTypeModifiedBy)
          VALUES (p_foodTypeName, p_foodTypeIsActive, CURRENT_TIMESTAMP, p_foodTypeCreatedBy, CURRENT_TIMESTAMP, p_foodTypeModifiedBy);
      END IF;
      RETURN QUERY (
          SELECT operation, json_build_object(
            'FoodTypeId', FoodTypeID,
            'FoodTypeName', FoodTypeName,
            'FoodTypeIsActive', FoodTypeIsActive,
            'FoodTypeCreatedDate', FoodTypeCreatedDate,
            'FoodTypeCreatedBy', FoodTypeCreatedBy,
            'FoodTypeModifiedDate', FoodTypeModifiedDate,
            'FoodTypeModifiedBy', FoodTypeModifiedBy
          )
          FROM FoodType
          WHERE FoodTypeName = p_foodTypeName
          LIMIT 1
        );
    END;
    $$ LANGUAGE plpgsql;