如何从postgres函数中选择特定列?

时间:2017-06-28 09:52:36

标签: sql postgresql select

我们说我有以下postgres功能:

[Route("api/[controller]")]
public class JwtController : Controller
{
    private readonly JwtIssuerOptions _jwtOptions;
    private readonly ILogger _logger;
    private readonly JsonSerializerSettings _serializerSettings;

    public JwtController(IOptions<JwtIssuerOptions> jwtOptions, ILoggerFactory loggerFactory)
    {
        _jwtOptions = jwtOptions.Value;
        ThrowIfInvalidOptions(_jwtOptions);

        _logger = loggerFactory.CreateLogger<JwtController>();

        _serializerSettings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented
        };
    }

    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Get([FromForm] string Username, string Password)
    {
        var applicationUser = new ApplicationUser();
        applicationUser.UserName = Username;
        applicationUser.Password = Password;
        var identity = await GetClaimsIdentity(applicationUser);
        if (identity == null)
        {
            _logger.LogInformation($"Invalid username({applicationUser.UserName}) or password ({applicationUser.Password})");
            return BadRequest("Invalid credentials");
        }

        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, applicationUser.UserName),
            new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
            new Claim(JwtRegisteredClaimNames.Iat,
                ToUnixExpochDate(_jwtOptions.IssuedAt).ToString(),
                ClaimValueTypes.Integer64),
            identity.FindFirst("Disney")
        };

        //Create the JWT security token and encode it.
        var jwt = new JwtSecurityToken(
            issuer: _jwtOptions.Issuer,
            audience: _jwtOptions.Audience,
            claims:claims,
            notBefore:_jwtOptions.NotBefore,
            expires:_jwtOptions.Expiration,
            signingCredentials:_jwtOptions.SigningCredentials);

        var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

        //Serialize and return the response.
        var response = new
        {
            access_token = encodedJwt,
            expires_in = (int)_jwtOptions.ValidFor.TotalSeconds
        };

        var json = JsonConvert.SerializeObject(response, _serializerSettings);
        return new OkObjectResult(json);
    }

    private static void ThrowIfInvalidOptions(JwtIssuerOptions options)
    {
        if (options == null) throw new ArgumentNullException(nameof(options));

        if (options.ValidFor <= TimeSpan.Zero)
        {
            throw new ArgumentException("Must be a non-zero TimeSpan.", nameof(JwtIssuerOptions.ValidFor));
        }

        if (options.SigningCredentials == null)
        {
            throw new ArgumentNullException(nameof(JwtIssuerOptions.SigningCredentials));
        }

        if (options.JtiGenerator == null)
        {
            throw new ArgumentNullException(nameof(JwtIssuerOptions.JtiGenerator));
        }
    }

    private static long ToUnixExpochDate(DateTime date)
        => (long)Math.Round((date.ToUniversalTime() -
            new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero))
            .TotalSeconds);

    private Task<ClaimsIdentity> GetClaimsIdentity(ApplicationUser user)
    {
        if (user.UserName == "mickey" && user.Password == "mouse")
        {
            return Task.FromResult(new ClaimsIdentity(
                new GenericIdentity(user.UserName, "Token"),
                new[]
                {
                    new Claim("Disney", "mickey")
                }));
        }

        if (user.UserName == "notmickey" && user.Password == "mouse")
        {
            return Task.FromResult(new ClaimsIdentity(
                new GenericIdentity(user.UserName, "Token"),
                new Claim[] { }));
        }

        return Task.FromResult<ClaimsIdentity>(null);
    }
}

我可以从这个功能中选择:

CREATE OR REPLACE FUNCTION get_summary(
  IN param INT)
  RETURNS TABLE (
    value NUMERIC,
    amount NUMERIC) AS $$
BEGIN

  RETURN QUERY
  SELECT sum(value) AS value, sum(amount) AS amount FROM ...

END;
$$ LANGUAGE plpgsql;

但如果我想这样选择怎么办:

SELECT * FROM get_summary(10);

但后来我收到以下错误:

SELECT value, amount FROM get_summary(10);

如何从postgres函数中选择特定列?

1 个答案:

答案 0 :(得分:3)

尝试使用表的别名 例如:

CREATE OR REPLACE FUNCTION get_summary(
  IN param INT)
  RETURNS TABLE (
    value NUMERIC,
    amount NUMERIC) AS $$
BEGIN

  RETURN QUERY
  SELECT sum(t.value), sum(t.amount) AS amount FROM your_table t

END;
$$ LANGUAGE plpgsql;

或试试这个:

SELECT t.value, t.amount FROM get_summary(10) t;